diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-03-31 11:00:40 +0200 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-03-31 11:05:25 -0700 |
commit | 1c330e67c837ab56b208ebf827ac422b21818824 (patch) | |
tree | 7d2b6cdee19dd97788856655efd7434d4fa48221 /test/files/pos/t8460.scala | |
parent | 5e795fc8bb53a016d0dff4127d83df4192f1cc13 (diff) | |
download | scala-1c330e67c837ab56b208ebf827ac422b21818824.tar.gz scala-1c330e67c837ab56b208ebf827ac422b21818824.tar.bz2 scala-1c330e67c837ab56b208ebf827ac422b21818824.zip |
SI-8460 Fix regression in divergent implicit recovery
Implicit search detects likely cycles by looking at the stack of
open implicits and checking the same implicit appears twice, and
if the second occurrence is trying satisfy an implicit search for
a "dominant" type.
Originally, this condition immediately failed the entire implicit
search. However, since Scala 2.10, this mechanism has been refined to
continue searching after the first divergent implicit is detected.
If a second divergence is found, we fail immediately. If the followup
search fails, we report the first divergence. Otherwise, we
take the successful result.
This mechanism was originally built around exceptions. This proved
to be fragile, and was refactored in SI-7291 / accaa314 to instead
use the `Context.errors` to control the process.
But, since that change, the pattern of implicits in scalanlp/breeze
and Shapeless have been prone to reporting the divergent implicit
errors where they used to recover.
So long as we left the `DivergentImplictTypeError` that originates
from a nested implicit search in `context.errors`, we are unable to
successfully typecheck other candidates. This commit instead
stashes the first such error away in `DivergentImplicitRecovery`,
to clear the way for the alternative path to succeed.
We must retain any other divergent implicit errors, as witnessed by
test/files/neg/t2031.scala, which loops unless we retain divergent
implicit errors that we don't stash in `DivergentImplicitRecovery`.
Diffstat (limited to 'test/files/pos/t8460.scala')
-rw-r--r-- | test/files/pos/t8460.scala | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/test/files/pos/t8460.scala b/test/files/pos/t8460.scala new file mode 100644 index 0000000000..10d2ed432c --- /dev/null +++ b/test/files/pos/t8460.scala @@ -0,0 +1,25 @@ +object tan extends UFunc { + implicit def ImplDouble: Impl[Double, Double] = ??? +} + +trait UFunc { + trait TC[+A] + type Impl[V, VR] = UFunc.UImpl[this.type, V, VR] +} + +object UFunc { + class UImpl[A, B, C] + implicit def implicitDoubleUTag[Tag, V, VR](implicit conv: V=>Double, impl: UImpl[Tag, Double, VR]):UImpl[Tag, V, VR] = ??? + +} + +object Test { + implicitly[tan.Impl[Double, Double]] + // we should discard the one and only divergent implicit (`implicitDoubleUTag`) + // This is done under `scalac-hash v2.10.4 test.scala`, but not under + // `scalac-hash v2.10.4 -Xdivergence211 test.scala` + // + // This seems to be because the companion implicits contain redundant entries + // + +} |