aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/ast/TreeTypeMap.scala80
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala4
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala4
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala6
-rw-r--r--src/dotty/tools/dotc/core/Scopes.scala16
-rw-r--r--src/dotty/tools/dotc/core/Substituters.scala2
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala19
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala19
-rw-r--r--src/dotty/tools/dotc/core/Types.scala53
-rw-r--r--src/dotty/tools/dotc/transform/FullParameterization.scala6
10 files changed, 151 insertions, 58 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/src/dotty/tools/dotc/ast/TreeTypeMap.scala
index 2adc6cd5d..bb8937aed 100644
--- a/src/dotty/tools/dotc/ast/TreeTypeMap.scala
+++ b/src/dotty/tools/dotc/ast/TreeTypeMap.scala
@@ -15,9 +15,13 @@ import Denotations._, Decorators._
* @param ownerMap A function that translates owners of top-level local symbols
* defined in the mapped tree.
* @param treeMap A transformer that translates all encountered subtrees in
- * prefix traversal order.
- * @param substFrom The symbols that need to be substituted
- * @param substTo The substitution targets
+ * prefix traversal orders
+ * @param oldOwners Previous owners. If a top-level local symbol in the mapped tree
+ * has one of these as an owner, the owner is replaced by the corresponding
+ * symbol in `newOwners`.
+ * @param newOwners New owners, replacing previous owners.
+ * @param substFrom The symbols that need to be substituted.
+ * @param substTo The substitution targets.
*
* The reason the substitution is broken out from the rest of the type map is
* that all symbols have to be substituted at the same time. If we do not do this,
@@ -30,28 +34,64 @@ import Denotations._, Decorators._
*/
final class TreeTypeMap(
val typeMap: Type => Type = IdentityTypeMap,
- val ownerMap: Symbol => Symbol = identity _,
val treeMap: tpd.Tree => tpd.Tree = identity _,
+ val oldOwners: List[Symbol] = Nil,
+ val newOwners: List[Symbol] = Nil,
val substFrom: List[Symbol] = Nil,
val substTo: List[Symbol] = Nil)(implicit ctx: Context) extends tpd.TreeMap {
import tpd._
- def mapType(tp: Type) = typeMap(tp).substSym(substFrom, substTo)
+ /** If `sym` is one of `oldOwners`, replace by corresponding symbol in `newOwners` */
+ def mapOwner(sym: Symbol) = {
+ def loop(from: List[Symbol], to: List[Symbol]): Symbol =
+ if (from.isEmpty) sym
+ else if (sym eq from.head) to.head
+ else loop(from.tail, to.tail)
+ loop(oldOwners, newOwners)
+ }
+
+ /** Replace occurrences of `This(oldOwner)` in some prefix of a type
+ * by the corresponding `This(newOwner)`.
+ */
+ private val mapOwnerThis = new TypeMap {
+ private def mapPrefix(from: List[Symbol], to: List[Symbol], tp: Type): Type = from match {
+ case Nil => tp
+ case (cls: ClassSymbol) :: from1 => mapPrefix(from1, to.tail, tp.substThis(cls, to.head.thisType))
+ case _ :: from1 => mapPrefix(from1, to.tail, tp)
+ }
+ def apply(tp: Type): Type = tp match {
+ case tp: NamedType => tp.derivedSelect(mapPrefix(oldOwners, newOwners, tp.prefix))
+ case _ => mapOver(tp)
+ }
+ }
+
+ def mapType(tp: Type) =
+ mapOwnerThis(typeMap(tp).substSym(substFrom, substTo))
+
+ private def updateDecls(prevStats: List[Tree], newStats: List[Tree]): Unit =
+ if (prevStats.isEmpty) assert(newStats.isEmpty)
+ else {
+ prevStats.head match {
+ case pdef: MemberDef =>
+ val prevSym = pdef.symbol
+ val newSym = newStats.head.symbol
+ val newCls = newSym.owner.asClass
+ if (prevSym != newSym) newCls.replace(prevSym, newSym)
+ case _ =>
+ }
+ updateDecls(prevStats.tail, newStats.tail)
+ }
override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = treeMap(tree) match {
case impl @ Template(constr, parents, self, body) =>
val tmap = withMappedSyms(impl.symbol :: impl.constr.symbol :: Nil)
- val constr1 = tmap.transformSub(constr)
val parents1 = parents mapconserve transform
- var self1 = transformDefs(self :: Nil)._2.head
+ val (_, constr1 :: self1 :: Nil) = transformDefs(constr :: self :: Nil)
val body1 = tmap.transformStats(body)
- body1 foreach {
- case mdef: MemberDef =>
- val member = mdef.symbol
- member.owner.asClass.enter(member, replace = true)
- case _ =>
- }
- cpy.Template(impl)(constr1, parents1, self1, body1).withType(tmap.mapType(impl.tpe))
+ updateDecls(constr :: body, constr1 :: body1)
+ cpy.Template(impl)(
+ constr1.asInstanceOf[DefDef], parents1, self1.asInstanceOf[ValDef], body1)
+ .withType(tmap.mapType(impl.tpe))
case tree1 =>
tree1.withType(mapType(tree1.tpe)) match {
case id: Ident if tpd.needsSelect(id.tpe) =>
@@ -104,15 +144,19 @@ final class TreeTypeMap(
if (from eq to) this
else {
// assert that substitution stays idempotent, assuming its parts are
+ // TODO: It might be better to cater for the asserted-away conditions, by
+ // setting up a proper substitution abstraction with a compose operator that
+ // guarantees idempotence. But this might be too inefficient in some cases.
+ // We'll cross that bridge when we need to.
assert(!from.exists(substTo contains _))
assert(!to.exists(substFrom contains _))
+ assert(!from.exists(oldOwners contains _))
+ assert(!to.exists(newOwners contains _))
new TreeTypeMap(
typeMap,
- ownerMap andThen { sym =>
- val idx = from.indexOf(sym)
- if (idx >= 0) to(idx) else sym
- },
treeMap,
+ from ++ oldOwners,
+ to ++ newOwners,
from ++ substFrom,
to ++ substTo)
}
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index 49294718b..ab8cf89a7 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -244,12 +244,12 @@ object Trees {
private[this] var myTpe: T = _
/** Destructively set the type of the tree. This should be called only when it is known that
- * it is safe under sharing to do so. One user-case is in the withType method below
+ * it is safe under sharing to do so. One use-case is in the withType method below
* which implements copy-on-write. Another use-case is in method interpolateAndAdapt in Typer,
* where we overwrite with a simplified version of the type itself.
*/
private[dotc] def overwriteType(tpe: T) = {
- if (this.isInstanceOf[Template[_]]) assert(tpe.isInstanceOf[WithNonMemberSym], s"$this <--- $tpe")
+ if (this.isInstanceOf[Template[_]]) assert(tpe.isInstanceOf[WithFixedSym], s"$this <--- $tpe")
myTpe = tpe
}
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index c0ebf4d61..cb1a265c3 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -512,7 +512,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
new TreeTypeMap(substFrom = from, substTo = to).apply(tree)
def changeOwner(from: Symbol, to: Symbol)(implicit ctx: Context): ThisTree =
- new TreeTypeMap(ownerMap = (sym => if (sym == from) to else sym)).apply(tree)
+ new TreeTypeMap(oldOwners = from :: Nil, newOwners = to :: Nil).apply(tree)
def select(name: Name)(implicit ctx: Context): Select =
Select(tree, name)
@@ -522,7 +522,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def select(sym: Symbol)(implicit ctx: Context): Select =
untpd.Select(tree, sym.name).withType(
- if (ctx.erasedTypes) TermRef.withNonMemberSym(tree.tpe, sym.name.asTermName, sym.asTerm)
+ if (ctx.erasedTypes) TermRef.withFixedSym(tree.tpe, sym.name.asTermName, sym.asTerm)
else TermRef.withSigAndDenot(tree.tpe, sym.name.asTermName, sym.signature, sym.denot.asSeenFrom(tree.tpe)))
def selectWithSig(name: Name, sig: Signature)(implicit ctx: Context) =
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index f89a5ce46..896de25fd 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -356,6 +356,9 @@ object Flags {
// Flags following this one are not pickled
+ /** Symbol always defines a fresh named type */
+ final val Fresh = commonFlag(45, "<fresh>")
+
/** Symbol is defined in a super call */
final val InSuperCall = commonFlag(46, "<in supercall>")
@@ -434,7 +437,8 @@ object Flags {
final val FromStartFlags =
AccessFlags | Module | Package | Deferred | MethodOrHKCommon | Param | ParamAccessor | Scala2ExistentialCommon |
InSuperCall | Touched | Static | CovariantOrOuter | ContravariantOrLabel | ExpandedName | AccessorOrSealed |
- CaseAccessorOrTypeArgument | Frozen | Erroneous | ImplicitCommon | Permanent | SelfNameOrImplClass
+ CaseAccessorOrTypeArgument | Fresh | Frozen | Erroneous | ImplicitCommon | Permanent |
+ SelfNameOrImplClass
assert(FromStartFlags.isTermFlags && FromStartFlags.isTypeFlags)
// TODO: Should check that FromStartFlags do not change in completion
diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala
index c8252e02e..54317a496 100644
--- a/src/dotty/tools/dotc/core/Scopes.scala
+++ b/src/dotty/tools/dotc/core/Scopes.scala
@@ -37,7 +37,9 @@ object Scopes {
*/
private final val MaxRecursions = 1000
- class ScopeEntry private[Scopes] (val name: Name, val sym: Symbol, val owner: Scope) {
+ class ScopeEntry private[Scopes] (val name: Name, _sym: Symbol, val owner: Scope) {
+
+ var sym: Symbol = _sym
/** the next entry in the hash bucket
*/
@@ -249,6 +251,18 @@ object Scopes {
}
}
+ /** Replace symbol `prev` (if it exists in current scope) by symbol `replacement`.
+ * @pre `prev` and `replacement` have the same name.
+ */
+ final def replace(prev: Symbol, replacement: Symbol)(implicit ctx: Context): Unit = {
+ require(prev.name == replacement.name)
+ var e = lookupEntry(prev.name)
+ while (e ne null) {
+ if (e.sym == prev) e.sym = replacement
+ e = lookupNextEntry(e)
+ }
+ }
+
/** Lookup a symbol entry matching given name.
*/
override final def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala
index a7977dc2b..02d09d542 100644
--- a/src/dotty/tools/dotc/core/Substituters.scala
+++ b/src/dotty/tools/dotc/core/Substituters.scala
@@ -132,7 +132,7 @@ trait Substituters { this: Context =>
while (fs.nonEmpty) {
if (fs.head eq sym)
return tp match {
- case tp: WithNonMemberSym => NamedType.withNonMemberSym(tp.prefix, ts.head)
+ case tp: WithFixedSym => NamedType.withFixedSym(tp.prefix, ts.head)
case _ => substSym(tp.prefix, from, to, theMap) select ts.head
}
fs = fs.tail
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index c9777ebf6..aed55e49a 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -867,7 +867,7 @@ object SymDenotations {
TermRef.withSigAndDenot(owner.thisType, name.asTermName, signature, this)
def nonMemberTermRef(implicit ctx: Context): TermRef =
- TermRef.withNonMemberSym(owner.thisType, name.asTermName, symbol.asTerm)
+ TermRef.withFixedSym(owner.thisType, name.asTermName, symbol.asTerm)
/** The variance of this type parameter or type member as an Int, with
* +1 = Covariant, -1 = Contravariant, 0 = Nonvariant, or not a type parameter
@@ -1182,15 +1182,13 @@ object SymDenotations {
* someone does a findMember on a subclass.
* @param scope The scope in which symbol should be entered.
* If this is EmptyScope, the scope is `decls`.
- * @param replace Replace any existing symbol with same name.
- * This is always done if this denotes a package class.
*/
- def enter(sym: Symbol, scope: Scope = EmptyScope, replace: Boolean = false)(implicit ctx: Context): Unit = {
+ def enter(sym: Symbol, scope: Scope = EmptyScope)(implicit ctx: Context): Unit = {
val mscope = scope match {
case scope: MutableScope => scope
case _ => decls.asInstanceOf[MutableScope]
}
- if (replace || (this is PackageClass)) {
+ if (this is PackageClass) {
val entry = mscope.lookupEntry(sym.name)
if (entry != null) {
if (entry.sym == sym) return
@@ -1212,6 +1210,17 @@ object SymDenotations {
myMemberCache invalidate sym.name
}
+ /** Replace symbol `prev` (if defined in current class) by symbol `replacement`.
+ * If `prev` is not defined in current class, do nothing.
+ * @pre `prev` and `replacement` have the same name.
+ */
+ def replace(prev: Symbol, replacement: Symbol)(implicit ctx: Context): Unit = {
+ require(!(this is Frozen))
+ decls.asInstanceOf[MutableScope].replace(prev, replacement)
+ if (myMemberCache != null)
+ myMemberCache invalidate replacement.name
+ }
+
/** Delete symbol from current scope.
* Note: We require that this does not happen after the first time
* someone does a findMember on a subclass.
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 96819f627..0174f75cf 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -269,7 +269,8 @@ trait Symbols { this: Context =>
*/
def mapSymbols(originals: List[Symbol], ttmap: TreeTypeMap) =
if (originals forall (sym =>
- (ttmap.mapType(sym.info) eq sym.info) && (ttmap.ownerMap(sym.owner) eq sym.owner)))
+ (ttmap.mapType(sym.info) eq sym.info) &&
+ !(ttmap.oldOwners contains sym.owner)))
originals
else {
val copies: List[Symbol] = for (original <- originals) yield
@@ -285,11 +286,18 @@ trait Symbols { this: Context =>
}
(originals, copies).zipped foreach {(original, copy) =>
val odenot = original.denot
+ val oinfo = original.info match {
+ case ClassInfo(pre, _, parents, decls, selfInfo) =>
+ assert(original.isClass)
+ ClassInfo(pre, copy.asClass, parents, decls, selfInfo)
+ case oinfo => oinfo
+ }
copy.denot = odenot.copySymDenotation(
symbol = copy,
- owner = ttmap1.ownerMap(odenot.owner),
- info = ttmap1.mapType(odenot.info),
- privateWithin = ttmap1.ownerMap(odenot.privateWithin), // since this refers to outer symbols, need not include copies (from->to) in ownermap here.
+ owner = ttmap1.mapOwner(odenot.owner),
+ initFlags = odenot.flags &~ Frozen | Fresh,
+ info = ttmap1.mapType(oinfo),
+ privateWithin = ttmap1.mapOwner(odenot.privateWithin), // since this refers to outer symbols, need not include copies (from->to) in ownermap here.
annotations = odenot.annotations.mapConserve(ttmap1.apply))
}
copies
@@ -362,6 +370,9 @@ object Symbols {
final def asType(implicit ctx: Context): TypeSymbol = { assert(isType, s"isType called on not-a-Type $this"); asInstanceOf[TypeSymbol] }
final def asClass: ClassSymbol = asInstanceOf[ClassSymbol]
+ final def isFresh(implicit ctx: Context) =
+ lastDenot != null && (lastDenot is Fresh)
+
/** Special cased here, because it may be used on naked symbols in substituters */
final def isStatic(implicit ctx: Context): Boolean =
lastDenot != null && denot.isStatic
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index c8c5bd80e..bbec70404 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1150,7 +1150,7 @@ object Types {
case d: SymDenotation =>
if ( d.validFor.runId == ctx.runId
|| ctx.stillValid(d)
- || this.isInstanceOf[WithNonMemberSym]) d.current
+ || this.isInstanceOf[WithFixedSym]) d.current
else {
val newd = loadDenot
if (newd.exists) newd else d.staleSymbolError
@@ -1402,7 +1402,7 @@ object Types {
override def computeHash = doHash((name, sig), prefix)
}
- trait WithNonMemberSym extends NamedType {
+ trait WithFixedSym extends NamedType {
def fixedSym: Symbol
assert(fixedSym ne NoSymbol)
uncheckedSetSym(fixedSym)
@@ -1416,8 +1416,11 @@ object Types {
override def withSym(sym: Symbol, signature: Signature)(implicit ctx: Context): ThisType =
unsupported("withSym")
+ override def newLikeThis(prefix: Type)(implicit ctx: Context): NamedType =
+ NamedType.withFixedSym(prefix, fixedSym)
+
override def equals(that: Any) = that match {
- case that: WithNonMemberSym => this.prefix == that.prefix && (this.fixedSym eq that.fixedSym)
+ case that: WithFixedSym => this.prefix == that.prefix && (this.fixedSym eq that.fixedSym)
case _ => false
}
override def computeHash = doHash(fixedSym, prefix)
@@ -1435,8 +1438,8 @@ object Types {
override def computeHash = unsupported("computeHash")
}
- 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
+ final class TermRefWithFixedSym(prefix: Type, name: TermName, val fixedSym: TermSymbol) extends TermRef(prefix, name) with WithFixedSym
+ final class TypeRefWithFixedSym(prefix: Type, name: TypeName, val fixedSym: TypeSymbol) extends TypeRef(prefix, name) with WithFixedSym
/** Assert current phase does not have erasure semantics */
private def assertUnerased()(implicit ctx: Context) =
@@ -1449,9 +1452,9 @@ object Types {
def apply(prefix: Type, name: Name, denot: Denotation)(implicit ctx: Context) =
if (name.isTermName) TermRef(prefix, name.asTermName, denot)
else TypeRef(prefix, name.asTypeName, denot)
- def withNonMemberSym(prefix: Type, sym: Symbol)(implicit ctx: Context) =
- if (sym.isType) TypeRef.withNonMemberSym(prefix, sym.name.asTypeName, sym.asType)
- else TermRef.withNonMemberSym(prefix, sym.name.asTermName, sym.asTerm)
+ def withFixedSym(prefix: Type, sym: Symbol)(implicit ctx: Context) =
+ if (sym.isType) TypeRef.withFixedSym(prefix, sym.name.asTypeName, sym.asType)
+ else TermRef.withFixedSym(prefix, sym.name.asTermName, sym.asTerm)
def withSymAndName(prefix: Type, sym: Symbol, name: Name)(implicit ctx: Context): NamedType =
if (sym.isType) TypeRef.withSymAndName(prefix, sym.asType, name.asTypeName)
else TermRef.withSymAndName(prefix, sym.asTerm, name.asTermName)
@@ -1479,7 +1482,8 @@ object Types {
* 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 ((prefix eq NoPrefix) || denot.symbol.isFresh)
+ apply(prefix, denot.symbol.asTerm)
else denot match {
case denot: SymDenotation if denot.isCompleted => withSig(prefix, name, denot.signature)
case _ => all(prefix, name)
@@ -1489,8 +1493,8 @@ object Types {
/** 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))
+ def withFixedSym(prefix: Type, name: TermName, sym: TermSymbol)(implicit ctx: Context): TermRef =
+ unique(new TermRefWithFixedSym(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
@@ -1500,8 +1504,8 @@ object Types {
* (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)
- withNonMemberSym(prefix, name, sym)
+ if ((prefix eq NoPrefix) || sym.isFresh)
+ withFixedSym(prefix, name, sym)
else if (sym.defRunId != NoRunId && sym.isCompleted)
withSig(prefix, name, sym.signature) withSym (sym, sym.signature)
else
@@ -1511,7 +1515,7 @@ object Types {
* (which must be completed).
*/
def withSig(prefix: Type, sym: TermSymbol)(implicit ctx: Context): TermRef =
- if (prefix eq NoPrefix) withNonMemberSym(prefix, sym.name, sym)
+ if ((prefix eq NoPrefix) || sym.isFresh) withFixedSym(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 */
@@ -1519,9 +1523,12 @@ object Types {
unique(new TermRefWithSignature(prefix, name, sig))
/** 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 (prefix eq NoPrefix) withNonMemberSym(prefix, denot.symbol.asTerm.name, denot.symbol.asTerm)
- else withSig(prefix, name, sig)) withDenot denot
+ def withSigAndDenot(prefix: Type, name: TermName, sig: Signature, denot: Denotation)(implicit ctx: Context): TermRef = {
+ if ((prefix eq NoPrefix) || denot.symbol.isFresh)
+ withFixedSym(prefix, denot.symbol.asTerm.name, denot.symbol.asTerm)
+ else
+ withSig(prefix, name, sig)
+ } withDenot denot
}
object TypeRef {
@@ -1536,8 +1543,8 @@ object Types {
/** 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))
+ def withFixedSym(prefix: Type, name: TypeName, sym: TypeSymbol)(implicit ctx: Context): TypeRef =
+ unique(new TypeRefWithFixedSym(prefix, name, sym))
/** Create a type ref referring to given symbol with given name.
* This is very similar to TypeRef(Type, Symbol),
@@ -1546,12 +1553,14 @@ object Types {
* (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 ((prefix eq NoPrefix) || sym.isFresh) withFixedSym(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
+ def apply(prefix: Type, name: TypeName, denot: Denotation)(implicit ctx: Context): TypeRef = {
+ if ((prefix eq NoPrefix) || denot.symbol.isFresh) apply(prefix, denot.symbol.asType)
+ else apply(prefix, name)
+ } withDenot denot
}
// --- Other SingletonTypes: ThisType/SuperType/ConstantType ---------------------------
diff --git a/src/dotty/tools/dotc/transform/FullParameterization.scala b/src/dotty/tools/dotc/transform/FullParameterization.scala
index cdea5754c..698a57c61 100644
--- a/src/dotty/tools/dotc/transform/FullParameterization.scala
+++ b/src/dotty/tools/dotc/transform/FullParameterization.scala
@@ -204,11 +204,13 @@ trait FullParameterization {
.substDealias(origTParams, trefs)
.subst(origVParams, argRefs.map(_.tpe))
.substThisUnlessStatic(origClass, thisRef.tpe),
- ownerMap = (sym => if (sym eq origMeth) derived else sym),
treeMap = {
case tree: This if tree.symbol == origClass => thisRef
case tree => rewireTree(tree, Nil) orElse tree
- }).transform(originalDef.rhs)
+ },
+ oldOwners = origMeth :: Nil,
+ newOwners = derived :: Nil
+ ).transform(originalDef.rhs)
})
/** A forwarder expression which calls `derived`, passing along