diff --git a/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala b/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala index 8e7cfc688724..7965a8f4c880 100644 --- a/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala +++ b/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala @@ -61,11 +61,11 @@ object CollectEntryPoints{ val StringType = d.StringType // The given class has a main method. def hasJavaMainMethod(sym: Symbol): Boolean = - (toDenot(sym).info member nme.main).alternatives exists(x => isJavaMainMethod(x.symbol)) + (sym.info member nme.main).alternatives exists(x => isJavaMainMethod(x.symbol)) def fail(msg: String, pos: Position = sym.pos) = { ctx.warning( sym.name + - s" has a main method with parameter type Array[String], but ${toDenot(sym).fullName} will not be a runnable program.\n Reason: $msg", + s" has a main method with parameter type Array[String], but ${sym.fullName} will not be a runnable program.\n Reason: $msg", sourcePos(sym.pos) // TODO: make this next claim true, if possible // by generating valid main methods as static in module classes @@ -77,7 +77,7 @@ object CollectEntryPoints{ def failNoForwarder(msg: String) = { fail(s"$msg, which means no static forwarder can be generated.\n") } - val possibles = if (sym.flags is Flags.Module) (toDenot(sym).info nonPrivateMember nme.main).alternatives else Nil + val possibles = if (sym.flags is Flags.Module) (sym.info nonPrivateMember nme.main).alternatives else Nil val hasApproximate = possibles exists { m => m.info match { case MethodTpe(_, p :: Nil, _) => p.typeSymbol == defn.ArrayClass @@ -94,7 +94,7 @@ object CollectEntryPoints{ if (hasJavaMainMethod(companion)) failNoForwarder("companion contains its own main method") - else if (toDenot(companion).info.member(nme.main) != NoDenotation) + else if (companion.info.member(nme.main) != NoDenotation) // this is only because forwarders aren't smart enough yet failNoForwarder("companion contains its own main method (implementation restriction: no main is allowed, regardless of signature)") else if (companion.flags is Flags.Trait) @@ -103,7 +103,7 @@ object CollectEntryPoints{ // attempts to be java main methods. else (possibles exists(x=> isJavaMainMethod(x.symbol))) || { possibles exists { m => - toDenot(m.symbol).info match { + m.symbol.info match { case t: PolyType => fail("main methods cannot be generic.") case MethodTpe(paramNames, paramTypes, resultType) => diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index c3ad297c860b..a4e2a49464fd 100644 --- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -143,7 +143,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val externalEqualsNumNum: Symbol = defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumNum) val externalEqualsNumChar: Symbol = NoSymbol // ctx.requiredMethod(BoxesRunTimeTypeRef, nme.equalsNumChar) // this method is private val externalEqualsNumObject: Symbol = defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumObject) - val externalEquals: Symbol = defn.BoxesRunTimeClass.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol + val externalEquals: Symbol = defn.BoxesRunTimeClass.info.decl(nme.equals_).suchThat(_.info.firstParamTypes.size == 2).symbol val MaxFunctionArity: Int = Definitions.MaxImplementedFunctionArity val FunctionClass: Array[Symbol] = defn.FunctionClassPerRun() val AbstractFunctionClass: Array[Symbol] = defn.AbstractFunctionClassPerRun() @@ -169,9 +169,9 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } def isBox(sym: Symbol): Boolean = - Erasure.Boxing.isBox(sym) && sym.denot.owner != defn.UnitModuleClass + Erasure.Boxing.isBox(sym) && sym.owner != defn.UnitModuleClass def isUnbox(sym: Symbol): Boolean = - Erasure.Boxing.isUnbox(sym) && sym.denot.owner != defn.UnitModuleClass + Erasure.Boxing.isUnbox(sym) && sym.owner != defn.UnitModuleClass val primitives: Primitives = new Primitives { val primitives = new DottyPrimitives(ctx) @@ -256,16 +256,16 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma av.visitEnum(name, edesc, evalue) } case t: TypeApply if (t.fun.symbol == Predef_classOf) => - av.visit(name, t.args.head.tpe.classSymbol.denot.info.toTypeKind(bcodeStore)(innerClasesStore).toASMType) + av.visit(name, t.args.head.tpe.classSymbol.info.toTypeKind(bcodeStore)(innerClasesStore).toASMType) case t: tpd.Select => - if (t.symbol.denot.owner.is(Flags.JavaEnum)) { + if (t.symbol.owner.is(Flags.JavaEnum)) { val edesc = innerClasesStore.typeDescriptor(t.tpe.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the enumeration class. val evalue = t.symbol.name.mangledString // value the actual enumeration value. av.visitEnum(name, edesc, evalue) } else { - // println(i"not an enum: ${t.symbol} / ${t.symbol.denot.owner} / ${t.symbol.denot.owner.isTerm} / ${t.symbol.denot.owner.flags}") - assert(toDenot(t.symbol).name.is(DefaultGetterName), - s"${toDenot(t.symbol).name.debugString}") // this should be default getter. do not emmit. + // println(i"not an enum: ${t.symbol} / ${t.symbol.owner} / ${t.symbol.owner.isTerm} / ${t.symbol.owner.flags}") + assert(t.symbol.name.is(DefaultGetterName), + s"${t.symbol.name.debugString}") // this should be default getter. do not emmit. } case t: SeqLiteral => val arrAnnotV: AnnotationVisitor = av.visitArray(name) @@ -273,7 +273,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma arrAnnotV.visitEnd() case Apply(fun, args) if fun.symbol == defn.ArrayClass.primaryConstructor || - toDenot(fun.symbol).owner == defn.ArrayClass.linkedClass && fun.symbol.name == nme_apply => + fun.symbol.owner == defn.ArrayClass.linkedClass && fun.symbol.name == nme_apply => val arrAnnotV: AnnotationVisitor = av.visitArray(name) var actualArgs = if (fun.tpe.isImplicitMethod) { @@ -304,7 +304,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } // for the lazy val in ScalaSigBytes to be GC'ed, the invoker of emitAnnotations() should hold the ScalaSigBytes in a method-local var that doesn't escape. */ case t @ Apply(constr, args) if t.tpe.derivesFrom(JavaAnnotationClass) => - val typ = t.tpe.classSymbol.denot.info + val typ = t.tpe.classSymbol.info val assocs = assocsFromApply(t) val desc = innerClasesStore.typeDescriptor(typ.asInstanceOf[bcodeStore.int.Type]) // the class descriptor of the nested annotation class val nestedVisitor = av.visitAnnotation(name, desc) @@ -521,7 +521,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma if (!valid) { ctx.error( - i"""|compiler bug: created invalid generic signature for $sym in ${sym.denot.owner.showFullName} + i"""|compiler bug: created invalid generic signature for $sym in ${sym.owner.showFullName} |signature: $sig |if this is reproducible, please report bug at https://github.com/lampepfl/dotty/issues """.trim, sym.pos) @@ -540,7 +540,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def getGenericSignature(sym: Symbol, owner: Symbol): String = { ctx.atPhase(ctx.erasurePhase) { implicit ctx => val memberTpe = - if (sym.is(Flags.Method)) sym.denot.info + if (sym.is(Flags.Method)) sym.info else owner.denot.thisType.memberInfo(sym) getGenericSignature(sym, owner, memberTpe).orNull } @@ -555,14 +555,14 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val memberTpe = ctx.atPhase(ctx.erasurePhase) { implicit ctx => moduleClass.denot.thisType.memberInfo(sym) } val erasedMemberType = TypeErasure.erasure(memberTpe) - if (erasedMemberType =:= sym.denot.info) + if (erasedMemberType =:= sym.info) getGenericSignature(sym, moduleClass, memberTpe).orNull else null } private def getGenericSignature(sym: Symbol, owner: Symbol, memberTpe: Type)(implicit ctx: Context): Option[String] = if (needsGenericSignature(sym)) { - val erasedTypeSym = sym.denot.info.typeSymbol + val erasedTypeSym = sym.info.typeSymbol if (erasedTypeSym.isPrimitiveValueClass) { None } else { @@ -655,7 +655,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def fullName(sep: Char): String = sym.showFullName def fullName: String = sym.showFullName def simpleName: Name = sym.name - def javaSimpleName: String = toDenot(sym).name.mangledString // addModuleSuffix(simpleName.dropLocal) + def javaSimpleName: String = sym.name.mangledString // addModuleSuffix(simpleName.dropLocal) def javaBinaryName: String = javaClassName.replace('.', '/') // TODO: can we make this a string? addModuleSuffix(fullNameInternal('/')) def javaClassName: String = toDenot(sym).fullName.mangledString // addModuleSuffix(fullNameInternal('.')).toString def name: Name = sym.name @@ -665,8 +665,8 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma } // types - def info: Type = toDenot(sym).info - def tpe: Type = toDenot(sym).info // todo whats the differentce between tpe and info? + def info: Type = sym.info + def tpe: Type = sym.info // todo whats the differentce between tpe and info? def thisType: Type = toDenot(sym).thisType // tests @@ -746,7 +746,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma // navigation - def owner: Symbol = toDenot(sym).owner + def owner: Symbol = sym.owner def rawowner: Symbol = { originalOwner } @@ -760,7 +760,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma val r = toDenot(sym)(shiftedContext).maybeOwner.lexicallyEnclosingClass(shiftedContext) r } else NoSymbol - def parentSymbols: List[Symbol] = toDenot(sym).info.parents.map(_.typeSymbol) + def parentSymbols: List[Symbol] = sym.info.parents.map(_.typeSymbol) def superClass: Symbol = { val t = toDenot(sym).asClass.superClass if (t.exists) t @@ -803,7 +803,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma private def definedClasses(phase: Phase) = if (sym.isDefinedInCurrentRun) ctx.atPhase(phase) { implicit ctx => - toDenot(sym).info.decls.filter(_.isClass) + sym.info.decls.filter(_.isClass) } else Nil @@ -815,10 +815,10 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma else Nil } def fieldSymbols: List[Symbol] = { - toDenot(sym).info.decls.filter(p => p.isTerm && !p.is(Flags.Method)) + sym.info.decls.filter(p => p.isTerm && !p.is(Flags.Method)) } def methodSymbols: List[Symbol] = - for (f <- toDenot(sym).info.decls.toList if f.isMethod && f.isTerm && !f.isModule) yield f + for (f <- sym.info.decls.toList if f.isMethod && f.isTerm && !f.isModule) yield f def serialVUID: Option[Long] = None @@ -842,7 +842,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def superInterfaces: List[Symbol] = { val directlyInheritedTraits = decorateSymbol(sym).directlyInheritedTraits val directlyInheritedTraitsSet = directlyInheritedTraits.toSet - val allBaseClasses = directlyInheritedTraits.iterator.flatMap(_.symbol.asClass.baseClasses.drop(1)).toSet + val allBaseClasses = directlyInheritedTraits.iterator.flatMap(_.asClass.baseClasses.drop(1)).toSet val superCalls = superCallsMap.getOrElse(sym, Set.empty) val additional = (superCalls -- directlyInheritedTraitsSet).filter(_.is(Flags.Trait)) // if (additional.nonEmpty) @@ -856,7 +856,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma */ def isTopLevelModuleClass: Boolean = sym.isModuleClass && ctx.atPhase(ctx.flattenPhase) { implicit ctx => - toDenot(sym).owner.is(Flags.PackageClass) + sym.owner.is(Flags.PackageClass) } /** @@ -874,7 +874,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma def addRemoteRemoteExceptionAnnotation: Unit = () def samMethod(): Symbol = - toDenot(sym).info.abstractTermMembers.headOption.getOrElse(toDenot(sym).info.member(nme.apply)).symbol + sym.info.abstractTermMembers.headOption.getOrElse(sym.info.member(nme.apply)).symbol } diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index c7017a8f547c..28cd05f3dd5d 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -1094,9 +1094,9 @@ object desugar { Literal(Constant(scala.Symbol(str))) case Quote(expr) => if (expr.isType) - TypeApply(ref(defn.QuotedType_applyR), List(expr)) + TypeApply(ref(defn.QuotedType_apply.termRef), List(expr)) else - Apply(ref(defn.QuotedExpr_applyR), expr) + Apply(ref(defn.QuotedExpr_apply.termRef), expr) case InterpolatedString(id, segments) => val strs = segments map { case ts: Thicket => ts.trees.head diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index c87ff6b059ba..17d4c8b5a7b1 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -625,7 +625,7 @@ class Definitions { lazy val Product_productPrefixR = ProductClass.requiredMethodRef(nme.productPrefix) def Product_productPrefix(implicit ctx: Context) = Product_productPrefixR.symbol lazy val LanguageModuleRef = ctx.requiredModule("scala.language") - def LanguageModuleClass(implicit ctx: Context) = LanguageModuleRef.symbol.moduleClass.asClass + def LanguageModuleClass(implicit ctx: Context) = LanguageModuleRef.moduleClass.asClass lazy val NonLocalReturnControlType: TypeRef = ctx.requiredClassRef("scala.runtime.NonLocalReturnControl") lazy val SelectableType: TypeRef = ctx.requiredClassRef("scala.Selectable") @@ -638,16 +638,12 @@ class Definitions { lazy val QuotedExprModuleType = ctx.requiredModuleRef("scala.quoted.Expr") def QuotedExprModule(implicit ctx: Context) = QuotedExprModuleType.symbol - lazy val QuotedExpr_applyR = QuotedExprModule.requiredMethodRef(nme.apply) - def QuotedExpr_apply(implicit ctx: Context) = QuotedExpr_applyR.symbol - - lazy val QuotedExpr_spliceR = QuotedExprClass.requiredMethod(nme.UNARY_~) - def QuotedExpr_~(implicit ctx: Context) = QuotedExpr_spliceR.symbol - lazy val QuotedExpr_runR = QuotedExprClass.requiredMethodRef(nme.run) - def QuotedExpr_run(implicit ctx: Context) = QuotedExpr_runR.symbol + def QuotedExpr_apply(implicit ctx: Context) = QuotedExprModule.requiredMethod(nme.apply) + def QuotedExpr_~(implicit ctx: Context) = QuotedExprClass.requiredMethod(nme.UNARY_~) + def QuotedExpr_run(implicit ctx: Context) =QuotedExprClass.requiredMethodRef(nme.run) lazy val QuotedExprsModule = ctx.requiredModule("scala.quoted.Exprs") - def QuotedExprsClass(implicit ctx: Context) = QuotedExprsModule.symbol.asClass + def QuotedExprsClass(implicit ctx: Context) = QuotedExprsModule.asClass lazy val QuotedTypeType = ctx.requiredClassRef("scala.quoted.Type") def QuotedTypeClass(implicit ctx: Context) = QuotedTypeType.symbol.asClass @@ -668,10 +664,9 @@ class Definitions { def Unpickler_unpickleType = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleType") lazy val TastyUniverseModule = ctx.requiredModule("scala.tasty.Universe") - def TastyUniverseModuleClass(implicit ctx: Context) = TastyUniverseModule.symbol.asClass + def TastyUniverseModuleClass(implicit ctx: Context) = TastyUniverseModule.moduleClass.asClass - lazy val TastyUniverse_compilationUniverseR = TastyUniverseModule.requiredMethod("compilationUniverse") - def TastyUniverse_compilationUniverse(implicit ctx: Context) = TastyUniverse_compilationUniverseR.symbol + lazy val TastyUniverse_compilationUniverse = TastyUniverseModule.requiredMethod("compilationUniverse") lazy val EqType = ctx.requiredClassRef("scala.Eq") def EqClass(implicit ctx: Context) = EqType.symbol.asClass diff --git a/compiler/src/dotty/tools/dotc/core/Denotations.scala b/compiler/src/dotty/tools/dotc/core/Denotations.scala index 54993ce45cf6..4ace9fed3549 100644 --- a/compiler/src/dotty/tools/dotc/core/Denotations.scala +++ b/compiler/src/dotty/tools/dotc/core/Denotations.scala @@ -21,6 +21,7 @@ import printing.Printer import io.AbstractFile import config.Config import util.common._ +import util.Stats import collection.mutable.ListBuffer import Decorators.SymbolIteratorDecorator @@ -174,6 +175,7 @@ object Denotations { abstract class Denotation(val symbol: Symbol) extends PreDenotation with printing.Showable { type AsSeenFromResult <: Denotation + Stats.record("Denotation") /** The type info of the denotation, exists only for non-overloaded denotations */ def info(implicit ctx: Context): Type @@ -287,35 +289,6 @@ object Denotations { denot.symbol } - def requiredMethod(name: PreName)(implicit ctx: Context): TermSymbol = - info.member(name.toTermName).requiredSymbol(_ is Method).asTerm - def requiredMethodRef(name: PreName)(implicit ctx: Context): TermRef = - requiredMethod(name).termRef - - def requiredMethod(name: PreName, argTypes: List[Type])(implicit ctx: Context): TermSymbol = { - info.member(name.toTermName).requiredSymbol { x => - (x is Method) && { - x.info.paramInfoss match { - case paramInfos :: Nil => paramInfos.corresponds(argTypes)(_ =:= _) - case _ => false - } - } - }.asTerm - } - def requiredMethodRef(name: PreName, argTypes: List[Type])(implicit ctx: Context): TermRef = - requiredMethod(name, argTypes).termRef - - def requiredValue(name: PreName)(implicit ctx: Context): TermSymbol = - info.member(name.toTermName).requiredSymbol(_.info.isParameterless).asTerm - def requiredValueRef(name: PreName)(implicit ctx: Context): TermRef = - requiredValue(name).termRef - - def requiredClass(name: PreName)(implicit ctx: Context): ClassSymbol = - info.member(name.toTypeName).requiredSymbol(_.isClass).asClass - - def requiredType(name: PreName)(implicit ctx: Context): TypeSymbol = - info.member(name.toTypeName).requiredSymbol(_.isType).asType - /** The alternative of this denotation that has a type matching `targetType` when seen * as a member of type `site`, `NoDenotation` if none exists. */ @@ -1139,6 +1112,8 @@ object Denotations { def denot1: PreDenotation def denot2: PreDenotation + Stats.record("MultiPreDenotation") + assert(denot1.exists && denot2.exists, s"Union of non-existing denotations ($denot1) and ($denot2)") def first = denot1.first def last = denot2.last @@ -1290,7 +1265,7 @@ object Denotations { /** An exception for accessing symbols that are no longer valid in current run */ class StaleSymbol(msg: => String) extends Exception { - util.Stats.record("stale symbol") + Stats.record("stale symbol") override def getMessage() = msg } } diff --git a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala index a8a53da9ffa5..804c7cf3a384 100644 --- a/compiler/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/compiler/src/dotty/tools/dotc/core/SymDenotations.scala @@ -127,6 +127,8 @@ object SymDenotations { //assert(symbol.id != 4940, name) + Stats.record("SymDenotation") + override def hasUniqueSym: Boolean = exists /** Debug only @@ -158,14 +160,22 @@ object SymDenotations { private def adaptFlags(flags: FlagSet) = if (isType) flags.toTypeFlags else flags.toTermFlags /** Update the flag set */ - final def flags_=(flags: FlagSet): Unit = + final def flags_=(flags: FlagSet): Unit = { myFlags = adaptFlags(flags) + symbol.updateFlagsCache(this, myFlags) + } /** Set given flags(s) of this denotation */ - final def setFlag(flags: FlagSet): Unit = { myFlags |= flags } + final def setFlag(flags: FlagSet): Unit = { + myFlags |= flags + symbol.updateFlagsCache(this, myFlags) + } /** Unset given flags(s) of this denotation */ - final def resetFlag(flags: FlagSet): Unit = { myFlags &~= flags } + final def resetFlag(flags: FlagSet): Unit = { + myFlags &~= flags + symbol.updateFlagsCache(this, myFlags) + } /** Set applicable flags from `flags` which is a subset of {NoInits, PureInterface} */ final def setNoInitsFlags(flags: FlagSet): Unit = { @@ -224,7 +234,7 @@ object SymDenotations { indent += 1 if (myFlags is Touched) throw CyclicReference(this) - myFlags |= Touched + setFlag(Touched) // completions.println(s"completing ${this.debugString}") try completer.complete(this)(ctx.withPhase(validFor.firstPhaseId)) @@ -240,7 +250,7 @@ object SymDenotations { } else { if (myFlags is Touched) throw CyclicReference(this) - myFlags |= Touched + setFlag(Touched) completer.complete(this)(ctx.withPhase(validFor.firstPhaseId)) } @@ -257,6 +267,7 @@ object SymDenotations { */ if (Config.checkNoSkolemsInInfo) assertNoSkolems(tp) myInfo = tp + symbol.updateInfoCache(this, tp) } /** The name, except @@ -447,8 +458,10 @@ object SymDenotations { def isError: Boolean = false /** Make denotation not exist */ - final def markAbsent(): Unit = + final def markAbsent(): Unit = { myInfo = NoType + symbol.updateInfoCache(this, NoType) + } /** Is symbol known to not exist, or potentially not completed yet? */ final def unforcedIsAbsent(implicit ctx: Context): Boolean = @@ -580,13 +593,13 @@ object SymDenotations { myFlags.is(ModuleClass) && (myFlags.is(PackageClass) || isStatic) /** Is this denotation defined in the same scope and compilation unit as that symbol? */ - final def isCoDefinedWith(that: Symbol)(implicit ctx: Context) = - (this.effectiveOwner == that.effectiveOwner) && + final def isCoDefinedWith(other: Symbol)(implicit ctx: Context) = + (this.effectiveOwner == other.effectiveOwner) && ( !(this.effectiveOwner is PackageClass) - || this.unforcedIsAbsent || that.unforcedIsAbsent + || this.unforcedIsAbsent || other.unforcedIsAbsent || { // check if they are defined in the same file(or a jar) val thisFile = this.symbol.associatedFile - val thatFile = that.symbol.associatedFile + val thatFile = other.associatedFile ( thisFile == null || thatFile == null || thisFile.path == thatFile.path // Cheap possibly wrong check, then expensive normalization @@ -1162,11 +1175,31 @@ object SymDenotations { /** The type This(cls), where cls is this class, NoPrefix for all other symbols */ def thisType(implicit ctx: Context): Type = NoPrefix - override def typeRef(implicit ctx: Context): TypeRef = - TypeRef(owner.thisType, symbol) + private[this] var cachedRef: NamedType = null - override def termRef(implicit ctx: Context): TermRef = - TermRef(owner.thisType, symbol) + def namedRef(implicit ctx: Context): NamedType = { + if (cachedRef == null) { + val initl = initial + val thistpe = maybeOwner.thisType + if ((initl `ne` this) && (thistpe `eq` initl.maybeOwner.thisType)) + cachedRef = initial.namedRef + else { + Stats.record("namedRef create") + cachedRef = ctx.uniqueNamedTypes.newType(thistpe, symbol, isTerm) + } + } + cachedRef + } + + override def typeRef(implicit ctx: Context): TypeRef = namedRef match { + case ref: TypeRef => ref + case _ => defn.AnyClass.typeRef // case arises when compiling parser-stabiility-1.scala + } + + override def termRef(implicit ctx: Context): TermRef = namedRef match { + case ref: TermRef => ref + case _ => defn.EmptyPackageVal.termRef + } /** The variance of this type parameter or type member as an Int, with * +1 = Covariant, -1 = Contravariant, 0 = Nonvariant, or not a type parameter diff --git a/compiler/src/dotty/tools/dotc/core/Symbols.scala b/compiler/src/dotty/tools/dotc/core/Symbols.scala index 7cae7b1822ab..1bdfac0749bc 100644 --- a/compiler/src/dotty/tools/dotc/core/Symbols.scala +++ b/compiler/src/dotty/tools/dotc/core/Symbols.scala @@ -29,7 +29,7 @@ import Denotations.{ Denotation, SingleDenotation, MultiDenotation } import collection.mutable import io.AbstractFile import language.implicitConversions -import util.{NoSource, DotClass, Property} +import util.{NoSource, DotClass, Property, Stats} import scala.collection.JavaConverters._ import config.Printers.typr @@ -416,6 +416,8 @@ object Symbols { //assert(id != 723) + Stats.record("Symbol") + def coord: Coord = myCoord /** Set the coordinate of this class, this is only useful when the coordinate is * not known at symbol creation. This is the case for root symbols @@ -432,22 +434,43 @@ object Symbols { private[this] var lastDenot: SymDenotation = _ private[this] var checkedPeriod: Period = Nowhere + private[this] var cachedName: Name = _ + private[this] var cachedOwner: Symbol = _ + private[this] var cachedInfo: Type = _ + private[this] var cachedFlags: FlagSet = _ + private[core] def invalidateDenotCache() = { checkedPeriod = Nowhere } + private[core] def updateInfoCache(d: SymDenotation, info: Type) = + if (lastDenot `eq` d) cachedInfo = info + + private[core] def updateFlagsCache(d: SymDenotation, flags: FlagSet) = + if (lastDenot `eq` d) cachedFlags = flags + + private[this] def setLastDenot(d: SymDenotation) = { + lastDenot = d + cachedName = d.name + cachedOwner = d.maybeOwner + cachedInfo = d.infoOrCompleter + cachedFlags = d.flagsUNSAFE + } + /** Set the denotation of this symbol */ private[core] def denot_=(d: SymDenotation) = { - lastDenot = d + setLastDenot(d) checkedPeriod = Nowhere } /** The current denotation of this symbol */ final def denot(implicit ctx: Context): SymDenotation = { + Stats.record("Symbol.denot") val lastd = lastDenot if (checkedPeriod == ctx.period) lastd else computeDenot(lastd) } private def computeDenot(lastd: SymDenotation)(implicit ctx: Context): SymDenotation = { + Stats.record("Symbol.computeDenot") val now = ctx.period checkedPeriod = now if (lastd.validFor contains now) lastd else recomputeDenot(lastd) @@ -455,8 +478,9 @@ object Symbols { /** Overridden in NoSymbol */ protected def recomputeDenot(lastd: SymDenotation)(implicit ctx: Context) = { + Stats.record("Symbol.recomputeDenot") val newd = lastd.current.asInstanceOf[SymDenotation] - lastDenot = newd + setLastDenot(newd) newd } @@ -556,15 +580,12 @@ object Symbols { /** If this symbol satisfies predicate `p` this symbol, otherwise `NoSymbol` */ def filter(p: Symbol => Boolean): Symbol = if (p(this)) this else NoSymbol - /** The current name of this symbol */ - final def name(implicit ctx: Context): ThisName = denot.name.asInstanceOf[ThisName] - /** The source or class file from which this class or * the class containing this symbol was generated, null if not applicable. * Overridden in ClassSymbol */ def associatedFile(implicit ctx: Context): AbstractFile = - if (lastDenot == null) null else lastDenot.topLevelClass.symbol.associatedFile + if (lastDenot == null) null else lastDenot.topLevelClass.associatedFile /** The class file from which this class was generated, null if not applicable. */ final def binaryFile(implicit ctx: Context): AbstractFile = { @@ -572,6 +593,14 @@ object Symbols { if (file != null && file.extension == "class") file else null } + /** A trap to avoid calling x.symbol on something that is already a symbol. + * This would be expanded to `toDenot(x).symbol` which is guaraneteed to be + * the same as `x`. + * With the given setup, all such calls will give implicit-not found errors + */ + final def symbol(implicit ev: DontUseSymbolOnSymbol): Nothing = unsupported("symbol") + type DontUseSymbolOnSymbol + /** The source file from which this class was generated, null if not applicable. */ final def sourceFile(implicit ctx: Context): AbstractFile = { val file = associatedFile @@ -598,14 +627,168 @@ object Symbols { def pos: Position = if (coord.isPosition) coord.toPosition else NoPosition // ParamInfo types and methods - def isTypeParam(implicit ctx: Context) = denot.is(TypeParam) - def paramName(implicit ctx: Context) = name.asInstanceOf[ThisName] - def paramInfo(implicit ctx: Context) = denot.info + def isTypeParam(implicit ctx: Context) = is(TypeParam) + def paramName(implicit ctx: Context) = name + def paramInfo(implicit ctx: Context) = info def paramInfoAsSeenFrom(pre: Type)(implicit ctx: Context) = pre.memberInfo(this) - def paramInfoOrCompleter(implicit ctx: Context): Type = denot.infoOrCompleter + def paramInfoOrCompleter(implicit ctx: Context): Type = infoOrCompleter def paramVariance(implicit ctx: Context) = denot.variance def paramRef(implicit ctx: Context) = denot.typeRef +// -------- Cached SymDenotation facades ----------------------------------------------- + + private def ensureUpToDate()(implicit ctx: Context) = + if (checkedPeriod != ctx.period) computeDenot(lastDenot) + + /** The current name of this symbol */ + final def name(implicit ctx: Context): ThisName = { + Stats.record("Symbol.name") + ensureUpToDate() + cachedName.asInstanceOf[ThisName] + } + + /** The current name of this symbol */ + final def maybeOwner(implicit ctx: Context): Symbol = { + Stats.record("Symbol.owner") + ensureUpToDate() + cachedOwner + } + + def owner(implicit ctx: Context): Symbol = maybeOwner + + /** The symbol is completed: info is not a lazy type and attributes have defined values */ + final def isCompleted(implicit ctx: Context): Boolean = { + ensureUpToDate() + !cachedInfo.isInstanceOf[LazyType] + } + + /** The denotation is in train of being completed */ + final def isCompleting(implicit ctx: Context): Boolean = { + ensureUpToDate() + cachedInfo.isInstanceOf[LazyType] && cachedFlags.is(Touched) + } + + /** Make sure this denotation of this symbol is completed */ + final def ensureCompleted()(implicit ctx: Context): Unit = { + ensureUpToDate() + if (cachedInfo.isInstanceOf[LazyType]) denot.ensureCompleted() + } + + final def infoOrCompleter(implicit ctx: Context): Type = { + Stats.record("Symbol.info") + ensureUpToDate() + cachedInfo + } + + final def info(implicit ctx: Context): Type = { + val tp = infoOrCompleter + if (tp.isInstanceOf[LazyType]) denot.info else tp + } + + final private[dotc] def info_=(tp: Type)(implicit ctx: Context) = denot.info_=(tp) + + final def flags(implicit ctx: Context): FlagSet = { + ensureCompleted() + val res = cachedFlags + assert(res == denot.flags, i"was: ${denot.flags}, now: $res") + res + } + + final def flags_=(flags: FlagSet)(implicit ctx: Context): Unit = denot.flags_=(flags) + + private def isCurrent(fs: FlagSet) = + fs <= ( + if (cachedInfo.isInstanceOf[SymbolLoader]) FromStartFlags + else AfterLoadFlags) + + final def is(fs: FlagSet)(implicit ctx: Context) = { + Stats.record("Symbol.is") + ensureUpToDate() + (if (isCurrent(fs)) cachedFlags else flags).is(fs) + } + + /** Has this denotation one of the flags in `fs` set, whereas none of the flags + * in `butNot` are set? + */ + final def is(fs: FlagSet, butNot: FlagSet)(implicit ctx: Context) = { + Stats.record("Symbol.is") + ensureUpToDate() + (if (isCurrent(fs) && isCurrent(butNot)) cachedFlags else flags).is(fs, butNot) + } + + /** Has this denotation all of the flags in `fs` set? */ + final def is(fs: FlagConjunction)(implicit ctx: Context) = { + Stats.record("Symbol.is") + ensureUpToDate() + (if (isCurrent(fs)) cachedFlags else flags).is(fs) + } + + /** Has this denotation all of the flags in `fs` set, whereas none of the flags + * in `butNot` are set? + */ + final def is(fs: FlagConjunction, butNot: FlagSet)(implicit ctx: Context) = { + Stats.record("Symbol.is") + ensureUpToDate() + (if (isCurrent(fs) && isCurrent(butNot)) cachedFlags else flags).is(fs, butNot) + } + + final def exists(implicit ctx: Context): Boolean = lastDenot.exists // updating necessary, any denot will do + + final def isRoot(implicit ctx: Context): Boolean = { + ensureUpToDate() + (maybeOwner eq NoSymbol) && (name.toTermName == nme.ROOT || name == nme.ROOTPKG) + } + + final def isEmptyPackage(implicit ctx: Context): Boolean = { + ensureUpToDate() + name.toTermName == nme.EMPTY_PACKAGE && owner.isRoot + } + + def isPrimitiveValueClass(implicit ctx: Context) = { + ensureUpToDate() + maybeOwner == defn.ScalaPackageClass && defn.ScalaValueClasses().contains(this) + } + + /** Is this symbol a package object or its module class? */ + def isPackageObject(implicit ctx: Context): Boolean = { + ensureUpToDate() + val nameMatches = + if (isType) name == tpnme.PACKAGE.moduleClassName + else name == nme.PACKAGE + nameMatches && (owner is Package) && (this is Module) + } + +// -------- Loading nested predefined symbols ----------------------------- + + def requiredMethod(name: PreName)(implicit ctx: Context): TermSymbol = + info.member(name.toTermName).requiredSymbol(_ is Method).asTerm + def requiredMethodRef(name: PreName)(implicit ctx: Context): TermRef = + requiredMethod(name).termRef + + def requiredMethod(name: PreName, argTypes: List[Type])(implicit ctx: Context): TermSymbol = { + info.member(name.toTermName).requiredSymbol { x => + (x is Method) && { + x.info.paramInfoss match { + case paramInfos :: Nil => paramInfos.corresponds(argTypes)(_ =:= _) + case _ => false + } + } + }.asTerm + } + def requiredMethodRef(name: PreName, argTypes: List[Type])(implicit ctx: Context): TermRef = + requiredMethod(name, argTypes).termRef + + def requiredValue(name: PreName)(implicit ctx: Context): TermSymbol = + info.member(name.toTermName).requiredSymbol(_.info.isParameterless).asTerm + def requiredValueRef(name: PreName)(implicit ctx: Context): TermRef = + requiredValue(name).termRef + + def requiredClass(name: PreName)(implicit ctx: Context): ClassSymbol = + info.member(name.toTypeName).requiredSymbol(_.isClass).asClass + + def requiredType(name: PreName)(implicit ctx: Context): TypeSymbol = + info.member(name.toTypeName).requiredSymbol(_.isType).asType + // -------- Printing -------------------------------------------------------- /** The prefix string to be used when displaying this symbol without denotation */ @@ -708,6 +891,7 @@ object Symbols { } @sharable object NoSymbol extends Symbol(NoCoord, 0) { + override def owner(implicit ctx: Context): Symbol = throw new AssertionError("NoSymbol.owner") override def associatedFile(implicit ctx: Context): AbstractFile = NoSource.file override def recomputeDenot(lastd: SymDenotation)(implicit ctx: Context): SymDenotation = NoDenotation } @@ -797,5 +981,4 @@ object Symbols { @inline def newMutableSymbolMap[T]: MutableSymbolMap[T] = new MutableSymbolMap(new java.util.IdentityHashMap[Symbol, T]()) - } diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 3e85582bef81..c3e461678ed3 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1690,6 +1690,7 @@ object Types { /** The denotation currently denoted by this type */ final def denot(implicit ctx: Context): Denotation = { + record("NamedType.denot") val now = ctx.period // Even if checkedPeriod == now we still need to recheck lastDenotation.validFor // as it may have been mutated by SymDenotation#installAfter diff --git a/compiler/src/dotty/tools/dotc/core/Uniques.scala b/compiler/src/dotty/tools/dotc/core/Uniques.scala index f31dc4f389b8..ab9913d52701 100644 --- a/compiler/src/dotty/tools/dotc/core/Uniques.scala +++ b/compiler/src/dotty/tools/dotc/core/Uniques.scala @@ -53,16 +53,33 @@ object Uniques { e } + def newType(prefix: Type, designator: Designator, hc: Int, isTerm: Boolean): NamedType = + if (isTerm) new CachedTermRef(prefix, designator, hc) + else new CachedTypeRef(prefix, designator, hc) + + def newType(prefix: Type, designator: Designator, isTerm: Boolean)(implicit ctx: Context): NamedType = + newType(prefix, designator, doHash(null, designator, prefix), isTerm) + def enterIfNew(prefix: Type, designator: Designator, isTerm: Boolean)(implicit ctx: Context): NamedType = { val h = doHash(null, designator, prefix) if (monitored) recordCaching(h, classOf[NamedType]) - def newType = - if (isTerm) new CachedTermRef(prefix, designator, h) - else new CachedTypeRef(prefix, designator, h) - if (h == NotCached) newType + designator match { + case sym: Symbol => + val symd = sym.lastKnownDenotation + if (symd != null && symd.exists) { + val ref = symd.namedRef + if (prefix `eq` ref.prefix) { + record("namedRef reuse") + return ref + } + } + case _ => + } + if (h == NotCached) newType(prefix, designator, h, isTerm) else { val r = findPrevious(h, prefix, designator) - if ((r ne null) && (r.isTerm == isTerm)) r else addEntryAfterScan(newType) + if ((r ne null) && (r.isTerm == isTerm)) r + else addEntryAfterScan(newType(prefix, designator, h, isTerm)) } } } diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index 86d7866041ad..2379ddfc610b 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -172,7 +172,7 @@ class ClassfileParser( setClassInfo(classRoot, classInfo) setClassInfo(moduleRoot, staticInfo) } else if (result == Some(NoEmbedded)) { - for (sym <- List(moduleRoot.sourceModule.symbol, moduleRoot.symbol, classRoot.symbol)) { + for (sym <- List(moduleRoot.sourceModule, moduleRoot.symbol, classRoot.symbol)) { classRoot.owner.asClass.delete(sym) if (classRoot.owner == defn.ScalaShadowingPackageClass) { // Symbols in scalaShadowing are also added to scala diff --git a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala index f7dbda218e0e..29a311a16f1f 100644 --- a/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala @@ -351,7 +351,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas val owner = if (atEnd) loadingMirror.RootClass else readSymbolRef() def adjust(denot: Denotation) = { - val denot1 = denot.disambiguate(d => p(d.symbol)) + val denot1 = denot.disambiguate(p) val sym = denot1.symbol if (denot.exists && !denot1.exists) { // !!!DEBUG val alts = denot.alternatives map (d => d + ":" + d.info + "/" + d.signature) diff --git a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala index 5cd531338e6d..5c17f62a79da 100644 --- a/compiler/src/dotty/tools/dotc/interactive/Interactive.scala +++ b/compiler/src/dotty/tools/dotc/interactive/Interactive.scala @@ -231,8 +231,8 @@ object Interactive { val boundaryCtx = ctx.withOwner(boundary) def exclude(sym: Symbol) = sym.isAbsent || sym.is(Synthetic) || sym.is(Artifact) def addMember(name: Name, buf: mutable.Buffer[SingleDenotation]): Unit = - buf ++= prefix.member(name).altsWith(d => - !exclude(d) && d.symbol.isAccessibleFrom(prefix)(boundaryCtx)) + buf ++= prefix.member(name).altsWith(sym => + !exclude(sym) && sym.isAccessibleFrom(prefix)(boundaryCtx)) prefix.memberDenots(completionsFilter, addMember).map(_.symbol).toList } else Nil diff --git a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala index 6cd1ad06156a..f7ffb7289568 100644 --- a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala +++ b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala @@ -190,7 +190,7 @@ object LambdaLift { def traverse(tree: Tree)(implicit ctx: Context) = try { //debug val sym = tree.symbol - def enclosure = ctx.owner.enclosingMethod.symbol + def enclosure = ctx.owner.enclosingMethod def narrowTo(thisClass: ClassSymbol) = { val enclMethod = enclosure diff --git a/compiler/src/dotty/tools/dotc/transform/Mixin.scala b/compiler/src/dotty/tools/dotc/transform/Mixin.scala index 437a8a45af3c..04ececdc2b1b 100644 --- a/compiler/src/dotty/tools/dotc/transform/Mixin.scala +++ b/compiler/src/dotty/tools/dotc/transform/Mixin.scala @@ -132,7 +132,7 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase => initName, Protected | Synthetic | Method, sym.info, - coord = sym.symbol.coord).enteredAfter(thisPhase)) + coord = sym.coord).enteredAfter(thisPhase)) } }.asTerm diff --git a/compiler/src/dotty/tools/dotc/transform/TreeExtractors.scala b/compiler/src/dotty/tools/dotc/transform/TreeExtractors.scala index 7a5c5df9db98..680f21bff1ac 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeExtractors.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeExtractors.scala @@ -36,8 +36,8 @@ object TreeExtractors { object ValueClassUnbox { def unapply(t: Tree)(implicit ctx: Context): Option[Tree] = t match { case Apply(sel @ Select(ref, _), Nil) => - val d = ref.tpe.widenDealias.typeSymbol.denot - if (isDerivedValueClass(d) && (sel.symbol eq valueClassUnbox(d.asClass))) { + val sym = ref.tpe.widenDealias.typeSymbol + if (isDerivedValueClass(sym) && (sel.symbol eq valueClassUnbox(sym.asClass))) { Some(ref) } else None diff --git a/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala b/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala index a186ec0feee0..120424204274 100644 --- a/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala +++ b/compiler/src/dotty/tools/dotc/transform/ValueClasses.scala @@ -4,7 +4,6 @@ package transform import core._ import Types._ import Symbols._ -import SymDenotations._ import Contexts._ import Flags._ import StdNames._ @@ -13,7 +12,8 @@ import SymUtils._ /** Methods that apply to user-defined value classes */ object ValueClasses { - def isDerivedValueClass(d: SymDenotation)(implicit ctx: Context) = { + def isDerivedValueClass(sym: Symbol)(implicit ctx: Context): Boolean = { + val d = sym.denot !ctx.settings.XnoValueClasses.value && !d.isRefinementClass && d.isValueClass && @@ -33,27 +33,27 @@ object ValueClasses { } /** The member of a derived value class that unboxes it. */ - def valueClassUnbox(d: ClassDenotation)(implicit ctx: Context): Symbol = + def valueClassUnbox(cls: ClassSymbol)(implicit ctx: Context): Symbol = // (info.decl(nme.unbox)).orElse(...) uncomment once we accept unbox methods - d.classInfo.decls.find(_.is(ParamAccessor)) + cls.classInfo.decls.find(_.is(ParamAccessor)) /** For a value class `d`, this returns the synthetic cast from the underlying type to * ErasedValueType defined in the companion module. This method is added to the module * and further described in [[ExtensionMethods]]. */ - def u2evt(d: ClassDenotation)(implicit ctx: Context): Symbol = - d.linkedClass.info.decl(nme.U2EVT).symbol + def u2evt(cls: ClassSymbol)(implicit ctx: Context): Symbol = + cls.linkedClass.info.decl(nme.U2EVT).symbol /** For a value class `d`, this returns the synthetic cast from ErasedValueType to the * underlying type defined in the companion module. This method is added to the module * and further described in [[ExtensionMethods]]. */ - def evt2u(d: ClassDenotation)(implicit ctx: Context): Symbol = - d.linkedClass.info.decl(nme.EVT2U).symbol + def evt2u(cls: ClassSymbol)(implicit ctx: Context): Symbol = + cls.linkedClass.info.decl(nme.EVT2U).symbol /** The unboxed type that underlies a derived value class */ - def underlyingOfValueClass(d: ClassDenotation)(implicit ctx: Context): Type = - valueClassUnbox(d).info.resultType + def underlyingOfValueClass(sym: ClassSymbol)(implicit ctx: Context): Type = + valueClassUnbox(sym).info.resultType /** Whether a value class wraps itself */ def isCyclic(cls: ClassSymbol)(implicit ctx: Context): Boolean = { diff --git a/compiler/src/dotty/tools/dotc/transform/localopt/InlineLocalObjects.scala b/compiler/src/dotty/tools/dotc/transform/localopt/InlineLocalObjects.scala index 8134764fd3cf..64bff5521381 100644 --- a/compiler/src/dotty/tools/dotc/transform/localopt/InlineLocalObjects.scala +++ b/compiler/src/dotty/tools/dotc/transform/localopt/InlineLocalObjects.scala @@ -92,7 +92,7 @@ class InlineLocalObjects(val simplifyPhase: Simplify) extends Optimisation { case t @ NewCaseClassValDef(fun, args) if newFieldsMapping.contains(t.symbol) => val newFields = newFieldsMapping(t.symbol).values.toList val newFieldsDefs = newFields.zip(args).map { case (nf, arg) => - val rhs = arg.changeOwnerAfter(t.symbol, nf.symbol, simplifyPhase) + val rhs = arg.changeOwnerAfter(t.symbol, nf, simplifyPhase) ValDef(nf.asTerm, rhs) } val recreate = cpy.ValDef(t)(rhs = fun.appliedToArgs(newFields.map(x => ref(x)))) diff --git a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala index 9b6c128d023b..f0611878b666 100644 --- a/compiler/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/compiler/src/dotty/tools/dotc/typer/Inferencing.scala @@ -279,7 +279,7 @@ object Inferencing { case tp: TypeRef => val companion = tp.classSymbol.companionModule if (companion.exists) - companion.termRef.asSeenFrom(tp.prefix, companion.symbol.owner) + companion.termRef.asSeenFrom(tp.prefix, companion.owner) else NoType case _ => NoType }