diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 3 | ||||
-rw-r--r-- | test/files/neg/t6667.check | 13 | ||||
-rw-r--r-- | test/files/neg/t6667.scala | 10 | ||||
-rw-r--r-- | test/files/neg/t6667b.check | 13 | ||||
-rw-r--r-- | test/files/neg/t6667b.scala | 25 |
5 files changed, 63 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 8f32f0e653..a74470a9cd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -1399,11 +1399,12 @@ trait Implicits { val failstart = if (Statistics.canEnable) Statistics.startTimer(oftypeFailNanos) else null val succstart = if (Statistics.canEnable) Statistics.startTimer(oftypeSucceedNanos) else null + val wasAmbigious = result.isAmbiguousFailure // SI-6667, never search companions after an ambiguous error in in-scope implicits result = materializeImplicit(pt) // `materializeImplicit` does some preprocessing for `pt` // is it only meant for manifests/tags or we need to do the same for `implicitsOfExpectedType`? - if (result.isFailure) result = searchImplicit(implicitsOfExpectedType, false) + if (result.isFailure && !wasAmbigious) result = searchImplicit(implicitsOfExpectedType, false) if (result.isFailure) { context.updateBuffer(previousErrs) diff --git a/test/files/neg/t6667.check b/test/files/neg/t6667.check new file mode 100644 index 0000000000..43313fa4fe --- /dev/null +++ b/test/files/neg/t6667.check @@ -0,0 +1,13 @@ +t6667.scala:8: error: ambiguous implicit values: + both value inScope1 in object Test of type => C + and value inScope2 in object Test of type => C + match expected type C + implicitly[C]: Unit // C.companion was used; whereas the ambiguity should abort the implicit search. + ^ +t6667.scala:9: error: ambiguous implicit values: + both value inScope1 in object Test of type => C + and value inScope2 in object Test of type => C + match expected type C + implicitly[C] // ambiguity reported, rather than falling back to C.companion + ^ +two errors found diff --git a/test/files/neg/t6667.scala b/test/files/neg/t6667.scala new file mode 100644 index 0000000000..fb857ebd33 --- /dev/null +++ b/test/files/neg/t6667.scala @@ -0,0 +1,10 @@ +class C +object C { + implicit def companion = new C +} + +object Test { + implicit val inScope1, inScope2 = new C + implicitly[C]: Unit // C.companion was used; whereas the ambiguity should abort the implicit search. + implicitly[C] // ambiguity reported, rather than falling back to C.companion +} diff --git a/test/files/neg/t6667b.check b/test/files/neg/t6667b.check new file mode 100644 index 0000000000..99cea9a47c --- /dev/null +++ b/test/files/neg/t6667b.check @@ -0,0 +1,13 @@ +t6667b.scala:16: error: ambiguous implicit values: + both value a in object Test of type => Test.Box + and value b of type Test.Box + match expected type Test.Box + new Test() + ^ +t6667b.scala:19: error: ambiguous implicit values: + both value a in object Test of type => Test.Box + and value b of type Test.Box + match expected type Test.Box + new Test() + ^ +two errors found diff --git a/test/files/neg/t6667b.scala b/test/files/neg/t6667b.scala new file mode 100644 index 0000000000..4e64e1af17 --- /dev/null +++ b/test/files/neg/t6667b.scala @@ -0,0 +1,25 @@ +object Test { + abstract class Box { + val value: Int + } + + implicit val a: Box = new Box { + val value= 1 + } + + def main(args: Array[String]) { + implicit val b: Box= new Box { + val value= 2 + } + + new Object { + new Test() + } + // compare with: + new Test() + } +} + +class Test()(implicit x: Test.Box) { + println(x.value) +} |