diff options
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeTypeMap.scala | 80 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/tpd.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Flags.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Scopes.scala | 16 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Substituters.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 19 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 53 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/FullParameterization.scala | 6 |
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 |