diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index ed8b347679b5..2c95bc6a92e7 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -976,10 +976,23 @@ trait Implicits: then return NoMatchingImplicitsFailure val result0 = - try ImplicitSearch(pt, argument, span).bestImplicit + // If we are searching implicits when resolving an import symbol, start the search + // in the first enclosing context that does not have the same scope and owner as the current + // context. Without that precaution, an eligible implicit in the current scope + // would cause a cyclic reference error (if the import is named) or cause a + // spurious import skip (if the import is a wildcard import). See i12802 for a test case. + var searchCtx = ctx + if ctx.owner.isImport then + while + searchCtx = searchCtx.outer + (searchCtx.scope eq ctx.scope) && (searchCtx.owner eq ctx.owner.owner) + do () + + try ImplicitSearch(pt, argument, span)(using searchCtx).bestImplicit catch case ce: CyclicReference => ce.inImplicitSearch = true throw ce + end result0 val result = result0 match { diff --git a/tests/neg/i12802.scala b/tests/neg/i12802.scala new file mode 100644 index 000000000000..a73a4193f120 --- /dev/null +++ b/tests/neg/i12802.scala @@ -0,0 +1,12 @@ +trait M: + type X + object X: + def foo(): X = ??? + +transparent inline def m(using m: M): m.type = m + +def Test1 = + given M = new M{} + import m.* // error: no implicit argument of type M was found + val x: X = X.foo() + println(x) diff --git a/tests/pos/i10295.scala b/tests/pos/i10295.scala index 3ec7eefca0ac..44400ce29de6 100644 --- a/tests/pos/i10295.scala +++ b/tests/pos/i10295.scala @@ -10,9 +10,11 @@ def doSomething(body: M ?=> Unit) = body(using new M{}) def Test1 = given M = new M{} - import m.* - val x: X = X.foo() - println(x) + locally { + import m.* + val x: X = X.foo() + println(x) + } def Test2 = diff --git a/tests/pos/i12802.scala b/tests/pos/i12802.scala new file mode 100644 index 000000000000..e26ea433f2d6 --- /dev/null +++ b/tests/pos/i12802.scala @@ -0,0 +1,9 @@ +import scala.quoted._ + +object Boo: + def foo(using Quotes): Unit = + import quotes.reflect._ + given Option[Symbol] = Some[Symbol](???) + def bar(using Quotes): Unit = + import quotes.reflect.Symbol + given Option[Symbol] = Some[Symbol](???)