From 271aaf0435fa5b2d591203da4b351eb09f16a32e Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Fri, 20 Oct 2017 13:56:15 +0200 Subject: [PATCH 1/2] Fix #3348: use a new typeState in inferView `inferImplicit` has an useful invariant that the constraint doesn't change in the case of implicit resolution failure. However, this invariant may not hold if completions are triggered during implicit resolution. By create a new typeState for inferView, we ensure that the useful invariant holds in such cases. --- compiler/src/dotty/tools/dotc/typer/Typer.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 095ccd29bdfe..5757facc0029 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2224,9 +2224,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit if (isFullyDefined(wtp, force = ForceDegree.all) && ctx.typerState.constraint.ne(prevConstraint)) adapt(tree, pt) else err.typeMismatch(tree, pt, failure) - if (ctx.mode.is(Mode.ImplicitsEnabled)) - inferView(tree, pt) match { + if (ctx.mode.is(Mode.ImplicitsEnabled)) { + val nestedCtx = ctx.fresh.setNewTyperState() + inferView(tree, pt)(nestedCtx) match { case SearchSuccess(inferred, _, _, _) => + nestedCtx.typerState.commit() adapt(inferred, pt)(ctx.retractMode(Mode.ImplicitsEnabled)) case failure: SearchFailure => if (pt.isInstanceOf[ProtoType] && !failure.isInstanceOf[AmbiguousImplicits]) @@ -2236,6 +2238,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit tree else recover(failure) } + } else recover(NoImplicitMatches) } From dfa8593c4604657224f57db17014e4b7a0706a44 Mon Sep 17 00:00:00 2001 From: liu fengyun Date: Fri, 20 Oct 2017 17:05:42 +0200 Subject: [PATCH 2/2] add test case for #3348 --- tests/neg/i3348.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/neg/i3348.scala diff --git a/tests/neg/i3348.scala b/tests/neg/i3348.scala new file mode 100644 index 000000000000..d5a9c0566938 --- /dev/null +++ b/tests/neg/i3348.scala @@ -0,0 +1,10 @@ +class Test { + import Test.test + "Hello".toto // error +} + +object Test { + def test = { + implicitly[collection.generic.CanBuildFrom[List[Int], Int, List[Int]]] + } +}