New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
destructuring binds, implicit resolution, and declaration order #9130
Comments
Imported From: https://issues.scala-lang.org/browse/SI-9130?orig=1 |
@retronym said: Unfortunately, there is no way to explicitly annotated the type of an implicit val with a pattern on the LHS of the =. % qscala -Xprint:parser -e 'implicit val (a, b): (Int, Int) = (1, 2)'
[[syntax trees at end of parser]] // scalacmd6461168732762336959.scala
package <empty> {
object Main extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
def main(args: Array[String]): scala.Unit = {
final class $anon extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
<synthetic> <artifact> private[this] val x$1 = (scala.Tuple2(1, 2): @scala.unchecked: scala.Tuple2[Int, Int]) match {
case scala.Tuple2((a @ _), (b @ _)) => scala.Tuple2(a, b)
};
implicit val a = x$1._1;
implicit val b = x$1._2
};
new $anon()
}
}
} We should add a style checking rule to https://github.com/scala/scala-abide/blob/master/README.md to help find such implicits. It is probably that a future version of Scala will actually enforce that implicits are type annotated. |
@refried said: My goal was to produce two implicit instances with a single call and minimal boilerplate. |
@refried said: |
@refried said: Is there a ticket for getting rid of the "explicitly-annotated types" requirement? Declarations like these remind me of Java: implicit def encode[A](implicit A: EncodeJson[A]): EncodeJson[Success[A]] = EncodeJson[Success[A]](...) OTOH, I guess it's not too hard to work around if the rule you mentioned is the only one, "the typechecker may ignore [implicits] from preceding parts of the same source file". I just never knew this rule, and it felt very Heisenbuggy. Thanks again. |
@retronym said: object Test {
def foo = implicitly[Int]
implicit val (a:Int, b:String) : (Int, String) = (1,"")
} % qscalac -Xprint:parser sandbox/test.scala
[[syntax trees at end of parser]] // test.scala
package <empty> {
object Test extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
def foo = implicitly[Int];
<synthetic> <artifact> private[this] val x$1 = (scala.Tuple2(1, ""): @scala.unchecked: scala.Tuple2[Int, String]) match {
case scala.Tuple2((a @ (_: Int)), (b @ (_: String))) => scala.Tuple2(a, b)
};
implicit val a: Int = x$1._1;
implicit val b: String = x$1._2
}
} |
@refried said: Thanks for the help & insights & for the -Xprint:parser trick. |
@retronym said: Here's a prototype: https://github.com/retronym/scala/compare/topic/warn-discarded-implicit?expand=1 However, this does not take into account the way that implicit search participates in type inference. If the expected type of the implicit search contains an undetermined type variable, the discarded implicit might not appear viable after inference has occurred. See also #7486, in which a previous attempt at highlighting this sort of issue introduced a regression. |
@refried said: How does implicit search participate in type inference? Is it the thing where |
This caused me quite the literal headache today:
The code above compiles, but if you swap the order of A and B, it no longer will:
Very sad indeed.
The tuple has something to with it; this is ok:
The text was updated successfully, but these errors were encountered: