Skip to content

Always exclude package objects from the implicit scope #8458

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -584,7 +584,7 @@ trait ImplicitRunInfo {
addPath(pre.prefix)
}
}
else {
else if (!pre.symbol.isPackageObject || ctx.scala2CompatMode) {
comps += pre
addPath(pre.prefix)
}
Expand Down
45 changes: 45 additions & 0 deletions tests/neg/implicit-package-object.scala
Original file line number Diff line number Diff line change
@@ -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]]
}
13 changes: 7 additions & 6 deletions tests/pos/toplevel-opaque-xm/Logarithm_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
}
}
9 changes: 2 additions & 7 deletions tests/pos/toplevel-opaque-xm/Test_2.scala
Original file line number Diff line number Diff line change
@@ -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]
}