aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala2
-rw-r--r--src/dotty/tools/dotc/config/Config.scala3
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala2
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala4
-rw-r--r--src/dotty/tools/dotc/core/Scopes.scala2
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala4
-rw-r--r--src/dotty/tools/dotc/core/Types.scala142
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala2
-rw-r--r--src/dotty/tools/dotc/typer/ImportInfo.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala2
10 files changed, 121 insertions, 44 deletions
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 56cd35344..7cdd8b7ac 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -497,7 +497,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def select(sym: Symbol)(implicit ctx: Context): Select =
untpd.Select(tree, sym.name).withType(
- TermRef.withSig(tree.tpe, sym.name.asTermName, sym.signature, sym.denot.asSeenFrom(tree.tpe)))
+ TermRef.withSigAndDenot(tree.tpe, sym.name.asTermName, sym.signature, sym.denot.asSeenFrom(tree.tpe)))
def selectWithSig(name: Name, sig: Signature)(implicit ctx: Context) =
untpd.SelectWithSig(tree, name, sig)
diff --git a/src/dotty/tools/dotc/config/Config.scala b/src/dotty/tools/dotc/config/Config.scala
index 906d17380..6360e080f 100644
--- a/src/dotty/tools/dotc/config/Config.scala
+++ b/src/dotty/tools/dotc/config/Config.scala
@@ -48,4 +48,7 @@ object Config {
* variance of the underlying lambda class.
*/
final val checkLambdaVariance = false
+
+ /** Check that certain types cannot be created in erasedTypes phases */
+ final val checkUnerased = true
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala
index f67381ddc..c61c46858 100644
--- a/src/dotty/tools/dotc/core/Annotations.scala
+++ b/src/dotty/tools/dotc/core/Annotations.scala
@@ -68,7 +68,7 @@ object Annotations {
deferred(atp.classSymbol, implicit ctx => New(atp, args))
def makeAlias(sym: TermSymbol)(implicit ctx: Context) =
- apply(defn.AliasAnnot, List(Ident(TermRef.withSig(sym.owner.thisType, sym.name, sym.signature, sym))))
+ apply(defn.AliasAnnot, List(Ident(TermRef.withSigAndDenot(sym.owner.thisType, sym.name, sym.signature, sym))))
def makeChild(sym: Symbol)(implicit ctx: Context) =
apply(defn.ChildAnnot.typeRef.appliedTo(sym.owner.thisType.select(sym.name, sym)), Nil)
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index fa2292c60..557c80b21 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -424,7 +424,7 @@ object Denotations {
* and at signature `NotAMethod`.
*/
def valRef(implicit ctx: Context): TermRef =
- TermRef.withSig(symbol.owner.thisType, symbol.name.asTermName, Signature.NotAMethod, this)
+ TermRef.withSigAndDenot(symbol.owner.thisType, symbol.name.asTermName, Signature.NotAMethod, this)
/** The TermRef representing this term denotation at its original location
* at the denotation's signature.
@@ -432,7 +432,7 @@ object Denotations {
* denotation via a call to `info`.
*/
def termRefWithSig(implicit ctx: Context): TermRef =
- TermRef.withSig(symbol.owner.thisType, symbol.name.asTermName, signature, this)
+ TermRef.withSigAndDenot(symbol.owner.thisType, symbol.name.asTermName, signature, this)
/** The NamedType representing this denotation at its original location.
* Same as either `typeRef` or `termRefWithSig` depending whether this denotes a type or not.
diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala
index 426df83bc..c8252e02e 100644
--- a/src/dotty/tools/dotc/core/Scopes.scala
+++ b/src/dotty/tools/dotc/core/Scopes.scala
@@ -298,7 +298,7 @@ object Scopes {
while (e ne null) {
if (e.sym is Implicit) {
val d = e.sym.denot
- irefs += TermRef.withSig(NoPrefix, e.sym.asTerm.name, d.signature, e.sym.denot)
+ irefs += TermRef.withSigAndDenot(NoPrefix, d.name.asTermName, d.signature, d)
}
e = e.prev
}
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 310dde912..e60633bb6 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -830,10 +830,10 @@ object SymDenotations {
TermRef(owner.thisType, name.asTermName, this)
override def valRef(implicit ctx: Context): TermRef =
- TermRef.withSig(owner.thisType, name.asTermName, Signature.NotAMethod, this)
+ TermRef.withSigAndDenot(owner.thisType, name.asTermName, Signature.NotAMethod, this)
override def termRefWithSig(implicit ctx: Context): TermRef =
- TermRef.withSig(owner.thisType, name.asTermName, signature, this)
+ TermRef.withSigAndDenot(owner.thisType, name.asTermName, signature, this)
def nonMemberTermRef(implicit ctx: Context): TermRef =
TermRef.withNonMemberSym(owner.thisType, name.asTermName, symbol.asTerm)
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 46cb92832..a8bfe61e0 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -717,7 +717,7 @@ object Types {
/** The type <this . name> , reduced if possible */
def select(name: Name)(implicit ctx: Context): Type = name match {
case name: TermName =>
- TermRef(this, name)
+ TermRef.all(this, name)
case name: TypeName =>
val res = lookupRefined(name)
if (res.exists) res else TypeRef(this, name)
@@ -1327,7 +1327,7 @@ object Types {
override def isOverloaded(implicit ctx: Context) = denot.isOverloaded
private def rewrap(sd: SingleDenotation)(implicit ctx: Context) =
- TermRef.withSig(prefix, name, sd.signature, sd)
+ TermRef.withSigAndDenot(prefix, name, sd.signature, sd)
def alternatives(implicit ctx: Context): List[TermRef] =
denot.alternatives map rewrap
@@ -1357,7 +1357,7 @@ object Types {
sig != Signature.OverloadedSignature &&
symbol.exists) {
val ownSym = symbol
- TermRef(prefix, name).withDenot(asMemberOf(prefix).disambiguate(_ eq ownSym))
+ TermRef.all(prefix, name).withDenot(asMemberOf(prefix).disambiguate(_ eq ownSym))
}
else TermRef.withSig(prefix, name, sig)
}
@@ -1409,9 +1409,23 @@ object Types {
final class NonMemberTermRef(prefix: Type, name: TermName, val fixedSym: TermSymbol) extends TermRef(prefix, name) with WithNonMemberSym
final class NonMemberTypeRef(prefix: Type, name: TypeName, val fixedSym: TypeSymbol) extends TypeRef(prefix, name) with WithNonMemberSym
+ /** Compute prefix at current phase. If current phase has erasure semantics
+ * returns NoPrefix, otherwise the given prefix
+ */
+ private def atCurrentPhase(prefix: Type)(implicit ctx: Context) =
+ if (ctx.phase.erasedTypes) NoPrefix else prefix
+
+ /** Is the prefix seen at current phase the same as NoPrefix? */
+ private def isMissing(prefix: Type)(implicit ctx: Context) =
+ (prefix eq NoPrefix) || ctx.phase.erasedTypes
+
+ /** Assert current phase does not have erasure semantics */
+ private def assertUnerased()(implicit ctx: Context) =
+ if (Config.checkUnerased) assert(!ctx.phase.erasedTypes)
+
object NamedType {
def apply(prefix: Type, name: Name)(implicit ctx: Context) =
- if (name.isTermName) TermRef(prefix, name.asTermName)
+ if (name.isTermName) TermRef.all(prefix, name.asTermName)
else TypeRef(prefix, name.asTypeName)
def apply(prefix: Type, name: Name, denot: Denotation)(implicit ctx: Context) =
if (name.isTermName) TermRef(prefix, name.asTermName, denot)
@@ -1422,58 +1436,100 @@ object Types {
}
object TermRef {
- def apply(prefix: Type, name: TermName)(implicit ctx: Context): TermRef =
- ctx.uniqueNamedTypes.enterIfNew(prefix, name).asInstanceOf[TermRef]
+ /** Create term ref with given name, without specifying a signature.
+ * Its meaning is the (potentially multi-) denotation of the member(s)
+ * of prefix with given name.
+ */
+ def all(prefix: Type, name: TermName)(implicit ctx: Context): TermRef = {
+ ctx.uniqueNamedTypes.enterIfNew(atCurrentPhase(prefix), name).asInstanceOf[TermRef]
+ }
+
+ /** Create term ref referring to given symbol, taking the signature
+ * from the symbol if it is completed, or creating a term ref without
+ * signature, if symbol is not yet completed.
+ */
def apply(prefix: Type, sym: TermSymbol)(implicit ctx: Context): TermRef =
withSymAndName(prefix, sym, sym.name)
+ /** Create term ref to given initial denotation, taking the signature
+ * from the denotation if it is completed, or creating a term ref without
+ * signature, if denotation is not yet completed.
+ */
def apply(prefix: Type, name: TermName, denot: Denotation)(implicit ctx: Context): TermRef = {
- if (prefix eq NoPrefix) apply(prefix, denot.symbol.asTerm)
+ if (isMissing(prefix)) apply(prefix, denot.symbol.asTerm)
else denot match {
case denot: SymDenotation if denot.isCompleted => withSig(prefix, name, denot.signature)
- case _ => apply(prefix, name)
+ case _ => all(prefix, name)
}
} withDenot denot
+ /** Create a non-member term ref (which cannot be reloaded using `member`),
+ * with given prefix, name, and signature
+ */
def withNonMemberSym(prefix: Type, name: TermName, sym: TermSymbol)(implicit ctx: Context): TermRef =
- unique(new NonMemberTermRef(prefix, name, sym))
-
+ unique(new NonMemberTermRef(atCurrentPhase(prefix), name, sym))
+
+ /** Create a term ref referring to given symbol with given name, taking the signature
+ * from the symbol if it is completed, or creating a term ref without
+ * signature, if symbol is not yet completed. This is very similar to TermRef(Type, Symbol),
+ * except for two differences:
+ * (1) The symbol might not yet have a denotation, so the name needs to be given explicitly.
+ * (2) The name in the term ref need not be the same as the name of the Symbol.
+ */
def withSymAndName(prefix: Type, sym: TermSymbol, name: TermName)(implicit ctx: Context): TermRef =
- if (prefix eq NoPrefix)
+ if (isMissing(prefix))
withNonMemberSym(prefix, name, sym)
else if (sym.defRunId != NoRunId && sym.isCompleted)
withSig(prefix, name, sym.signature) withSym (sym, sym.signature)
else
- apply(prefix, name) withSym (sym, Signature.NotAMethod)
+ all(prefix, name) withSym (sym, Signature.NotAMethod)
+ /** Create a term ref to given symbol, taking the signature from the symbol
+ * (which must be completed).
+ */
def withSig(prefix: Type, sym: TermSymbol)(implicit ctx: Context): TermRef =
- unique(withSig(prefix, sym.name, sym.signature).withSym(sym, sym.signature))
+ if (isMissing(prefix)) withNonMemberSym(prefix, sym.name, sym)
+ else withSig(prefix, sym.name, sym.signature).withSym(sym, sym.signature)
+ /** Create a term ref with given prefix, name and signature */
def withSig(prefix: Type, name: TermName, sig: Signature)(implicit ctx: Context): TermRef =
- unique(new TermRefWithSignature(prefix, name, sig))
+ unique(new TermRefWithSignature(atCurrentPhase(prefix), name, sig))
- def withSig(prefix: Type, name: TermName, sig: Signature, denot: Denotation)(implicit ctx: Context): TermRef =
- (if (prefix eq NoPrefix) apply(prefix, denot.symbol.asTerm)
+ /** Create a term ref with given prefix, name, signature, and initial denotation */
+ def withSigAndDenot(prefix: Type, name: TermName, sig: Signature, denot: Denotation)(implicit ctx: Context): TermRef =
+ (if (isMissing(prefix)) withNonMemberSym(prefix, denot.symbol.asTerm.name, denot.symbol.asTerm)
else withSig(prefix, name, sig)) withDenot denot
}
object TypeRef {
+ /** Create type ref with given prefix and name */
def apply(prefix: Type, name: TypeName)(implicit ctx: Context): TypeRef =
- ctx.uniqueNamedTypes.enterIfNew(prefix, name).asInstanceOf[TypeRef]
+ ctx.uniqueNamedTypes.enterIfNew(atCurrentPhase(prefix), name).asInstanceOf[TypeRef]
+ /** Create type ref to given symbol */
def apply(prefix: Type, sym: TypeSymbol)(implicit ctx: Context): TypeRef =
withSymAndName(prefix, sym, sym.name)
+ /** Create a non-member type ref (which cannot be reloaded using `member`),
+ * with given prefix, name, and symbol.
+ */
def withNonMemberSym(prefix: Type, name: TypeName, sym: TypeSymbol)(implicit ctx: Context): TypeRef =
- unique(new NonMemberTypeRef(prefix, name, sym))
+ unique(new NonMemberTypeRef(atCurrentPhase(prefix), name, sym))
+ /** Create a type ref referring to given symbol with given name.
+ * This is very similar to TypeRef(Type, Symbol),
+ * except for two differences:
+ * (1) The symbol might not yet have a denotation, so the name needs to be given explicitly.
+ * (2) The name in the type ref need not be the same as the name of the Symbol.
+ */
def withSymAndName(prefix: Type, sym: TypeSymbol, name: TypeName)(implicit ctx: Context): TypeRef =
- if (prefix eq NoPrefix) withNonMemberSym(prefix, name, sym)
+ if (isMissing(prefix)) withNonMemberSym(prefix, name, sym)
else apply(prefix, name).withSym(sym, Signature.NotAMethod)
+ /** Create a type ref with given name and initial denotation */
def apply(prefix: Type, name: TypeName, denot: Denotation)(implicit ctx: Context): TypeRef =
- (if (prefix eq NoPrefix) apply(prefix, denot.symbol.asType) else apply(prefix, name)) withDenot denot
+ (if (isMissing(prefix)) apply(prefix, denot.symbol.asType) else apply(prefix, name)) withDenot denot
}
// --- Other SingletonTypes: ThisType/SuperType/ConstantType ---------------------------
@@ -1520,8 +1576,10 @@ object Types {
final class CachedConstantType(value: Constant) extends ConstantType(value)
object ConstantType {
- def apply(value: Constant)(implicit ctx: Context) =
+ def apply(value: Constant)(implicit ctx: Context) = {
+ assertUnerased()
unique(new CachedConstantType(value))
+ }
}
case class LazyRef(refFn: () => Type) extends UncachedProxyType with ValueType {
@@ -1644,6 +1702,7 @@ object Types {
unchecked(tp1, tp2)
}
def unchecked(tp1: Type, tp2: Type)(implicit ctx: Context) = {
+ assertUnerased()
unique(new CachedAndType(tp1, tp2))
}
def make(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
@@ -1667,8 +1726,10 @@ object Types {
final class CachedOrType(tp1: Type, tp2: Type) extends OrType(tp1, tp2)
object OrType {
- def apply(tp1: Type, tp2: Type)(implicit ctx: Context) =
+ def apply(tp1: Type, tp2: Type)(implicit ctx: Context) = {
+ assertUnerased()
unique(new CachedOrType(tp1, tp2))
+ }
def make(tp1: Type, tp2: Type)(implicit ctx: Context): Type =
if (tp1 eq tp2) tp1 else apply(tp1, tp2)
}
@@ -1844,8 +1905,10 @@ object Types {
final class CachedExprType(resultType: Type) extends ExprType(resultType)
object ExprType {
- def apply(resultType: Type)(implicit ctx: Context) =
+ def apply(resultType: Type)(implicit ctx: Context) = {
+ assertUnerased()
unique(new CachedExprType(resultType))
+ }
}
case class PolyType(paramNames: List[TypeName])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => Type)
@@ -1907,10 +1970,10 @@ object Types {
def paramNum: Int
}
- case class MethodParam(binder: MethodType, paramNum: Int) extends ParamType with SingletonType {
+ abstract case class MethodParam(binder: MethodType, paramNum: Int) extends ParamType with SingletonType {
type BT = MethodType
override def underlying(implicit ctx: Context): Type = binder.paramTypes(paramNum)
- def copyBoundType(bt: BT) = MethodParam(bt, paramNum)
+ def copyBoundType(bt: BT) = new MethodParamImpl(bt, paramNum)
// need to customize hashCode and equals to prevent infinite recursion for dep meth types.
override def computeHash = addDelta(System.identityHashCode(binder), paramNum)
@@ -1924,6 +1987,15 @@ object Types {
override def toString = s"MethodParam(${binder.paramNames(paramNum)})"
}
+ class MethodParamImpl(binder: MethodType, paramNum: Int) extends MethodParam(binder, paramNum)
+
+ object MethodParam {
+ def apply(binder: MethodType, paramNum: Int)(implicit ctx: Context): MethodParam = {
+ assertUnerased()
+ new MethodParamImpl(binder, paramNum)
+ }
+ }
+
case class PolyParam(binder: PolyType, paramNum: Int) extends ParamType {
type BT = PolyType
def copyBoundType(bt: BT) = PolyParam(bt, paramNum)
@@ -2111,15 +2183,17 @@ object Types {
def selfType(implicit ctx: Context): Type = {
if (selfTypeCache == null) {
def fullRef = fullyAppliedRef(cls.typeRef, cls.typeParams)
- selfTypeCache = selfInfo match {
- case NoType =>
- fullRef
- case tp: Type =>
- if (cls is Module) tp else AndType(tp, fullRef)
- case self: Symbol =>
- assert(!(cls is Module))
- AndType(self.info, fullRef)
- }
+ selfTypeCache =
+ if (ctx.erasedTypes) fullRef
+ else selfInfo match {
+ case NoType =>
+ fullRef
+ case tp: Type =>
+ if (cls is Module) tp else AndType(tp, fullRef)
+ case self: Symbol =>
+ assert(!(cls is Module))
+ AndType(self.info, fullRef)
+ }
}
selfTypeCache
}
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index da1492d61..571b37eb0 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -310,7 +310,7 @@ trait ImplicitRunInfo { self: RunInfo =>
def addRef(companion: TermRef): Unit = {
val compSym = companion.symbol
if (compSym is Package)
- addRef(TermRef(companion, nme.PACKAGE))
+ addRef(TermRef.withSig(companion, nme.PACKAGE, Signature.NotAMethod))
else if (compSym.exists)
comps += companion.asSeenFrom(pre, compSym.owner).asInstanceOf[TermRef]
}
diff --git a/src/dotty/tools/dotc/typer/ImportInfo.scala b/src/dotty/tools/dotc/typer/ImportInfo.scala
index 18e5db209..9152a8d54 100644
--- a/src/dotty/tools/dotc/typer/ImportInfo.scala
+++ b/src/dotty/tools/dotc/typer/ImportInfo.scala
@@ -86,7 +86,7 @@ class ImportInfo(val sym: Symbol, val selectors: List[untpd.Tree], val isRootImp
for {
renamed <- reverseMapping.keys
denot <- pre.member(reverseMapping(renamed)).altsWith(_ is Implicit)
- } yield TermRef.withSig(pre, renamed, denot.signature, denot)
+ } yield TermRef.withSigAndDenot(pre, renamed, denot.signature, denot)
}
/** The root import symbol hidden by this symbol, or NoSymbol if no such symbol is hidden.
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index e1f860589..1cfd03e4c 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1143,7 +1143,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val altDenots = ref.denot.alternatives
typr.println(i"adapt overloaded $ref with alternatives ${altDenots map (_.info)}%, %")
val alts = altDenots map (alt =>
- TermRef.withSig(ref.prefix, ref.name, alt.info.signature, alt))
+ TermRef.withSigAndDenot(ref.prefix, ref.name, alt.info.signature, alt))
def expectedStr = err.expectedTypeStr(pt)
resolveOverloaded(alts, pt) match {
case alt :: Nil =>