diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 32c4a2eb3be9..9f546dc896ca 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -507,10 +507,10 @@ trait ImplicitRunInfo { val incomplete: mutable.Set[Type] = mutable.Set() /** Is `sym` an anchor type for which givens may exist? Anchor types are classes, - * opaque type aliases, and abstract types, but not type parameters + * opaque type aliases, and abstract types, but not type parameters or package objects. */ def isAnchor(sym: Symbol) = - sym.isClass && !sym.is(Package) + sym.isClass && !sym.is(Package) && (!sym.isPackageObject || ctx.scala2CompatMode) || sym.isOpaqueAlias || sym.is(Deferred, butNot = Param) @@ -584,7 +584,7 @@ trait ImplicitRunInfo { addPath(pre.prefix) } } - else { + else if (!pre.symbol.isPackageObject || ctx.scala2CompatMode) { comps += pre addPath(pre.prefix) } diff --git a/tests/neg/implicit-package-object.scala b/tests/neg/implicit-package-object.scala new file mode 100644 index 000000000000..deb276c94c05 --- /dev/null +++ b/tests/neg/implicit-package-object.scala @@ -0,0 +1,45 @@ +trait ToString[A] { + def print(a: A): Unit +} + +package A { + case class AA(text: String) + given ToString[AA] = aa => println(aa.text) + + opaque type AB = String + given ToString[AB] = ab => println(ab) + + opaque type AC = String + given ToString[AC] { + def print(ac: AC): Unit = println(ac) + } +} + +package B { + case class BA(text: String) + object BA { + given ToString[BA] = ba => println(ba.text) + } + + opaque type BB = String + object BB { + given ToString[BB] = bb => println(bb) + } + + opaque type BC = String + object BC { + given ToString[BC] { + def print(bc: BC): Unit = println(bc) + } + } +} + +object Test { + val AA = summon[ToString[A.AA]] // error + val AB = summon[ToString[A.AB]] // error, used to compile + val AC = summon[ToString[A.AC]] // error + + val BA = summon[ToString[B.BA]] + val BB = summon[ToString[B.BB]] + val BC = summon[ToString[B.BC]] +} diff --git a/tests/pos/toplevel-opaque-xm/Logarithm_1.scala b/tests/pos/toplevel-opaque-xm/Logarithm_1.scala index c9e4e439713b..884e29a1ad25 100644 --- a/tests/pos/toplevel-opaque-xm/Logarithm_1.scala +++ b/tests/pos/toplevel-opaque-xm/Logarithm_1.scala @@ -2,7 +2,7 @@ package logs opaque type Logarithm = Double -implicit object Logarithm { +object Logarithm { // These are the ways to lift to the logarithm type def apply(d: Double): Logarithm = math.log(d) @@ -13,10 +13,11 @@ implicit object Logarithm { // This is the first way to unlift the logarithm type def exponent(l: Logarithm): Double = l - // Extension methods define opaque types' public APIs - // This is the second way to unlift the logarithm type - def (x: Logarithm).toDouble: Double = math.exp(x) - def (x: Logarithm) + (y: Logarithm) = Logarithm(math.exp(x) + math.exp(y)) - def (x: Logarithm) * (y: Logarithm): Logarithm = Logarithm(x + y) + given AnyRef { + // This is the second way to unlift the logarithm type + def (x: Logarithm).toDouble: Double = math.exp(x) + def (x: Logarithm) + (y: Logarithm) = Logarithm(math.exp(x) + math.exp(y)) + def (x: Logarithm) * (y: Logarithm): Logarithm = Logarithm(x + y) + } } diff --git a/tests/pos/toplevel-opaque-xm/Test_2.scala b/tests/pos/toplevel-opaque-xm/Test_2.scala index b0e61aa41aaa..6ff16cd03c30 100644 --- a/tests/pos/toplevel-opaque-xm/Test_2.scala +++ b/tests/pos/toplevel-opaque-xm/Test_2.scala @@ -1,15 +1,10 @@ package logs -import Predef.{any2stringadd => _, _} - object Test { val l = Logarithm(1.0) val l2 = Logarithm(2.0) val l3 = l * l2 - val l4 = l + l2 // currently requires any2stringadd to be disabled because - // as a contextual implicit this takes precedence over the - // implicit scope implicit LogarithmOps. - // TODO: Remove any2stringadd - val d = Logarithm.toDouble(l3) + val l4 = l + l2 + val d = l3.toDouble val l5: Logarithm = (1.0).asInstanceOf[Logarithm] }