Skip to content

Commit 07ab9f4

Browse files
committed
Make implicit scope include companion objects of opaque types
1 parent 97b1e6d commit 07ab9f4

File tree

6 files changed

+26
-22
lines changed

6 files changed

+26
-22
lines changed

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,11 @@ object SymDenotations {
551551
/** Is this symbol an abstract type or type parameter? */
552552
final def isAbstractOrParamType(implicit ctx: Context) = this is DeferredOrTypeParam
553553

554+
/** Can this symbol have a companion module?
555+
* This is the case if it is a class or an opaque type alias.
556+
*/
557+
final def canHaveCompanion(implicit ctx: Context) = isClass || is(Opaque)
558+
554559
/** Is this the denotation of a self symbol of some class?
555560
* This is the case if one of two conditions holds:
556561
* 1. It is the symbol referred to in the selfInfo part of the ClassInfo

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -398,15 +398,15 @@ trait ImplicitRunInfo { self: Run =>
398398
override implicit protected val ctx: Context = liftingCtx
399399
override def stopAtStatic = true
400400
def apply(tp: Type) = tp match {
401-
case tp: TypeRef if tp.symbol.isAbstractOrAliasType =>
401+
case tp: TypeRef if !tp.symbol.canHaveCompanion =>
402402
val pre = tp.prefix
403403
def joinClass(tp: Type, cls: ClassSymbol) =
404404
AndType.make(tp, cls.typeRef.asSeenFrom(pre, cls.owner))
405405
val lead = if (tp.prefix eq NoPrefix) defn.AnyType else apply(tp.prefix)
406406
(lead /: tp.classSymbols)(joinClass)
407407
case tp: TypeVar =>
408408
apply(tp.underlying)
409-
case tp: AppliedType if !tp.tycon.typeSymbol.isClass =>
409+
case tp: AppliedType if !tp.tycon.typeSymbol.canHaveCompanion =>
410410
def applyArg(arg: Type) = arg match {
411411
case TypeBounds(lo, hi) => AndType.make(lo, hi)
412412
case WildcardType(TypeBounds(lo, hi)) => AndType.make(lo, hi)
@@ -444,21 +444,24 @@ trait ImplicitRunInfo { self: Run =>
444444
case tp: NamedType =>
445445
val pre = tp.prefix
446446
comps ++= iscopeRefs(pre)
447-
def addClassScope(cls: ClassSymbol): Unit = {
448-
def addRef(companion: TermRef): Unit = {
449-
val compSym = companion.symbol
450-
if (compSym is Package)
451-
addRef(companion.select(nme.PACKAGE))
452-
else if (compSym.exists)
453-
comps += companion.asSeenFrom(pre, compSym.owner).asInstanceOf[TermRef]
454-
}
455-
def addParentScope(parent: Type): Unit =
456-
iscopeRefs(tp.baseType(parent.typeSymbol)) foreach addRef
457-
val companion = cls.companionModule
447+
def addRef(companion: TermRef): Unit = {
448+
val compSym = companion.symbol
449+
if (compSym is Package)
450+
addRef(companion.select(nme.PACKAGE))
451+
else if (compSym.exists)
452+
comps += companion.asSeenFrom(pre, compSym.owner).asInstanceOf[TermRef]
453+
}
454+
def addCompanionOf(sym: Symbol) = {
455+
val companion = sym.companionModule
458456
if (companion.exists) addRef(companion.termRef)
459-
cls.classParents foreach addParentScope
460457
}
461-
tp.classSymbols(liftingCtx) foreach addClassScope
458+
def addClassScope(cls: ClassSymbol): Unit = {
459+
addCompanionOf(cls)
460+
for (parent <- cls.classParents; ref <- iscopeRefs(tp.baseType(parent.typeSymbol)))
461+
addRef(ref)
462+
}
463+
if (tp.widen.typeSymbol.is(Opaque)) addCompanionOf(tp.widen.typeSymbol)
464+
else tp.classSymbols(liftingCtx).foreach(addClassScope)
462465
case _ =>
463466
for (part <- tp.namedPartsWith(_.isType)) comps ++= iscopeRefs(part)
464467
}

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ class Namer { typer: Typer =>
621621
def createLinks(classTree: TypeDef, moduleTree: TypeDef)(implicit ctx: Context) = {
622622
val claz = ctx.effectiveScope.lookup(classTree.name)
623623
val modl = ctx.effectiveScope.lookup(moduleTree.name)
624-
if (modl.isClass && (claz.isClass || claz.is(Opaque))) {
624+
if (modl.isClass && claz.canHaveCompanion) {
625625
modl.registerCompanion(claz)
626626
claz.registerCompanion(modl)
627627
}

tests/neg/tagging.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ object tagging {
1515
ct
1616
}
1717

18-
import Tagged._
19-
2018
type @@[S, T] = Tagged[S, T]
2119

2220
implicit class UntagOps[S, T](st: S @@ T) extends AnyVal {

tests/pos/opaque.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ object opaquetypes {
2323
}
2424
object usesites {
2525
import opaquetypes._
26-
import Logarithm.LogarithmOps // todo: drop
2726
val l = Logarithm(1.0)
2827
val l2 = Logarithm(2.0)
29-
val l3 = l + l2
28+
val l3 = l * l2
29+
val l4 = l * l2
3030
val d = l3.toDouble
3131
val l4: Logarithm = (1.0).asInstanceOf[Logarithm]
3232
}

tests/pos/tagging.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ object tagging {
1515
ct
1616
}
1717

18-
import Tagged._
19-
2018
type @@[S, T] = Tagged[S, T]
2119

2220
implicit class UntagOps[S, T](st: S @@ T) extends AnyVal {

0 commit comments

Comments
 (0)