-
Notifications
You must be signed in to change notification settings - Fork 21
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
the implicit arguments of implicit conversions do not guide type inference #3346
Comments
Imported From: https://issues.scala-lang.org/browse/SI-3346?orig=1
|
@retronym said: http://gist.github.com/444680 I want one of the implicit conversions to be rejected as it results in a type that can't satisfy the context bound. But maybe I'm asking too much :) This is the motivating example from Scalaz: trait Identity[A] {
def mapply[F[_], B](f: F[A => B])(implicit ftr: Functor[F]): F[B] = f ∘ (_(value))
} scala> 1.mapply(Seq((_: Int) * 2))
res5: Seq[Int] = List(2)
scala> 1.mapply[Identity, Int]((_: Int) * 2)
res6: scalaz.Identity[Int] = 2
scala> 1 mapply ((_: Int) * 2)
<console>:12: error: type mismatch;
found : (Int) => Int
required: ?F[ (Int) => ?B ]
Note that implicit conversions are not applicable because they are ambiguous:
both method IdentityTo in trait Identitys of type [A](x: A)scalaz.Identity[A]
and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A]
are possible conversion functions from (Int) => Int to ?F[ (Int) => ?B ]
1 mapply ((_: Int) * 2)
^ |
@adriaanm said: |
@adriaanm said: |
@szeiger said: |
maxime.levesque said: This could be another incarnation of it : |
@adriaanm said: I really want to fix this, but it's quite the tightrope walk over the jagged teeth of backwards compatibility, performance, and spec conformance. |
@paulp said: See attached by the way, look at all those typevars coming from those zipped functions. This seems bad performancewise. |
@paulp said: |
@milessabin said: trait Foo[A]
implicit def fooString: Foo[String] = null
implicit def value[A](implicit foo: Foo[A]) = 5
implicitly[Int] // OK Whereas ... implicit def conversion[A](x: Int)(implicit foo: Foo[A]) = new {
def aMethod = 5
}
1.aMethod // Error: could not find implicit value for parameter foo: test.Foo[A] |
@Blaisorblade said: It seems that this branch (https://github.com/adriaanm/scala/tree/ticket/implicitly_depmet), the only one with a similar name, is quite unrelated. And you write:
|
@adriaanm said: |
@Blaisorblade said: |
@gkossakowski said: It leads to a very confusing error messages as demonstrated in sbt ticket. |
@xeno-by said (edited on Jul 24, 2013 9:01:49 PM UTC): Just for the record. Apart those scaladoc tests failing and blocking the build, we have only three failing tests in the main test suite, all coming from neg: 22:58 ~/Projects/Kepler_7692 (ticket/7692)$ t
Testing individual files
testing: [...]/files/neg/divergent-implicit.scala [FAILED]
testing: [...]/files/neg/t5578.scala [FAILED]
--- divergent-implicit-neg.log
+++ divergent-implicit.check
@@ -9,10 +9,8 @@
^
-divergent-implicit.scala:14: error: type mismatch;
- found : Test2.Foo
- required: Test2.Bar
+divergent-implicit.scala:14: error: diverging implicit expansion for type Test2.Baz => Test2.Bar
+starting with method baz2bar in object Test2
val x: Bar = new Foo
^
-divergent-implicit.scala:15: error: type mismatch;
- found : Test2.Baz
- required: Test2.Bar
+divergent-implicit.scala:15: error: diverging implicit expansion for type Test2.Foo => Test2.Bar
+starting with method foo2bar in object Test2
val y: Bar = new Baz--- t5578-neg.log
+++ t5578.check
@@ -1,5 +1,2 @@
-t5578.scala:33: error: type mismatch;
- found : NumericOpsExp.this.Plus[T]
- required: NumericOpsExp.this.Rep[T]
- (which expands to) NumericOpsExp.this.Exp[T]
+t5578.scala:33: error: No Manifest available for T.
def plus[T: Numeric](x: Rep[T], y: Rep[T]): Rep[T] = Plus[T](x,y)
testing: [...]/files/neg/t5845.scala [FAILED] |
@paulp said: object Test extends App {
trait Fundep[T, U]
class C { def y = "x" }
implicit val FundepStringC = new Fundep[String, C]{}
implicit def foo[T, U](x: T)(implicit y: Fundep[T, U]): U = ???
implicit def bar[T](x: T)(implicit y: Fundep[T, C]): C = ???
println("x".y)
} |
@xeno-by said (edited on Jul 24, 2013 9:15:36 PM UTC): Also, from what I can see, only a couple scaladoc tests + some neg tests have broken (of these only the divergence is arguable though making sense, the others just started working as they should), which gives hope that my provisional fix might need just a bit more polishing. What do you think? /cc @retronym @adriaanm. |
@hubertp said: |
@paulp said: I no longer have an opinion on such tradeoffs. |
@xeno-by said (edited on Jul 24, 2013 9:42:55 PM UTC): The divergence test failure does make sense. Previously the offending views were selected by implicit search and then subsequent typechecking caused resolution of their implicit parameters, which led to divergence. Now divergence happens during implicit search, which simply invalidates given views and the error says "expected X, got Y" meaning that no suitable implicit conversions were found. At a glance this makes sense to me. Does it to you? |
@Blaisorblade said: The following has some assumption on the change: it should make the actual Scalac behavior simpler to describe. Try documenting the current behavior (bugs included), try documenting the behavior with the patch, verify the latter is much simpler and actually understandable; in particular, the latter should be more declarative. Because of such bugs, Scalac typechecker's behavior feels random. To see a discussion of them, look no further than this blog post: (I also wonder whether something in there has to do with this bug, maybe seq2richseq? There's a comment from Adriaan Moors about another relation. But don't take me too seriously here, the details are a vague recollection from ages ago; my point is about why such bugs are bad). Moreover, it seems that the code which will break is (arguably) buggy anyway, even though without a fixed Scalac this is probably hard to see. And changes which fix implicit resolution and break code have gone in as late as 2.10 (IIRC). If wanted, one could support the transition somehow: make the new behavior optional and controlled by an option, or add a warning in 2.11 for code which will break (hard) and make the change for 2.12 (though I'd like things to go faster). Overall, I think we need a way to fix bugs which make (buggy) code compile. C++ compilers often broke buggy code, I don't think Scala needs better bug-to-bug compatibility. (Sorry for the length). |
@xeno-by said: |
@xeno-by said: |
relevant code from Implicits.scala
The text was updated successfully, but these errors were encountered: