Skip to content

Experiment: Replace type application encoding with native AppliedType #2898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
// to inner symbols of DefDef
// todo: somehow handle.

def parents: List[Type] = tp.parents
def parents: List[Type] = tp.parentsNEW
}


Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
ta.assignType(untpd.TypeDef(sym.name, TypeTree(sym.info)), sym)

def ClassDef(cls: ClassSymbol, constr: DefDef, body: List[Tree], superArgs: List[Tree] = Nil)(implicit ctx: Context): TypeDef = {
val firstParentRef :: otherParentRefs = cls.info.parents
val firstParentRef :: otherParentRefs = cls.info.parentRefs
val firstParent = cls.typeRef.baseTypeWithArgs(firstParentRef.symbol)
val superRef =
if (cls is Trait) TypeTree(firstParent)
Expand Down Expand Up @@ -261,7 +261,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def AnonClass(parents: List[Type], fns: List[TermSymbol], methNames: List[TermName])(implicit ctx: Context): Block = {
val owner = fns.head.owner
val parents1 =
if (parents.head.classSymbol.is(Trait)) parents.head.parents.head :: parents
if (parents.head.classSymbol.is(Trait)) parents.head.parentRefs.head :: parents
else parents
val cls = ctx.newNormalizedClassSymbol(owner, tpnme.ANON_FUN, Synthetic, parents1,
coord = fns.map(_.pos).reduceLeft(_ union _))
Expand Down
74 changes: 41 additions & 33 deletions compiler/src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ object SymDenotations {
| is not a subclass of ${owner.showLocated} where target is defined""")
else if (
!( isType // allow accesses to types from arbitrary subclasses fixes #4737
|| pre.baseTypeRef(cls).exists // ??? why not use derivesFrom ???
|| pre.derivesFrom(cls)
|| isConstructor
|| (owner is ModuleClass) // don't perform this check for static members
))
Expand Down Expand Up @@ -1266,10 +1266,10 @@ object SymDenotations {
private[this] var myMemberCache: LRUCache[Name, PreDenotation] = null
private[this] var myMemberCachePeriod: Period = Nowhere

/** A cache from types T to baseTypeRef(T, C) */
type BaseTypeRefMap = java.util.HashMap[CachedType, Type]
private[this] var myBaseTypeRefCache: BaseTypeRefMap = null
private[this] var myBaseTypeRefCachePeriod: Period = Nowhere
/** A cache from types T to baseType(T, C) */
type BaseTypeMap = java.util.HashMap[CachedType, Type]
private[this] var myBaseTypeCache: BaseTypeMap = null
private[this] var myBaseTypeCachePeriod: Period = Nowhere

private var baseDataCache: BaseData = BaseData.None
private var memberNamesCache: MemberNames = MemberNames.None
Expand All @@ -1282,14 +1282,14 @@ object SymDenotations {
myMemberCache
}

private def baseTypeRefCache(implicit ctx: Context): BaseTypeRefMap = {
if (myBaseTypeRefCachePeriod != ctx.period &&
(myBaseTypeRefCachePeriod.runId != ctx.runId ||
ctx.phases(myBaseTypeRefCachePeriod.phaseId).sameParentsStartId != ctx.phase.sameParentsStartId)) {
myBaseTypeRefCache = new BaseTypeRefMap
myBaseTypeRefCachePeriod = ctx.period
private def baseTypeCache(implicit ctx: Context): BaseTypeMap = {
if (myBaseTypeCachePeriod != ctx.period &&
(myBaseTypeCachePeriod.runId != ctx.runId ||
ctx.phases(myBaseTypeCachePeriod.phaseId).sameParentsStartId != ctx.phase.sameParentsStartId)) {
myBaseTypeCache = new BaseTypeMap
myBaseTypeCachePeriod = ctx.period
}
myBaseTypeRefCache
myBaseTypeCache
}

private def invalidateBaseDataCache() = {
Expand All @@ -1302,9 +1302,9 @@ object SymDenotations {
memberNamesCache = MemberNames.None
}

def invalidateBaseTypeRefCache() = {
myBaseTypeRefCache = null
myBaseTypeRefCachePeriod = Nowhere
def invalidateBaseTypeCache() = {
myBaseTypeCache = null
myBaseTypeCachePeriod = Nowhere
}

override def copyCaches(from: SymDenotation, phase: Phase)(implicit ctx: Context): this.type = {
Expand All @@ -1313,7 +1313,7 @@ object SymDenotations {
if (from.memberNamesCache.isValidAt(phase)) memberNamesCache = from.memberNamesCache
if (from.baseDataCache.isValidAt(phase)) {
baseDataCache = from.baseDataCache
myBaseTypeRefCache = from.baseTypeRefCache
myBaseTypeCache = from.baseTypeCache
}
case _ =>
}
Expand Down Expand Up @@ -1379,6 +1379,14 @@ object SymDenotations {
NoSymbol
}

/** The explicitly given self type (self types of modules are assumed to be
* explcitly given here).
*/
def givenSelfType(implicit ctx: Context) = classInfo.selfInfo match {
case tp: Type => tp
case self: Symbol => self.info
}

// ------ class-specific operations -----------------------------------

private[this] var myThisType: Type = null
Expand Down Expand Up @@ -1581,11 +1589,11 @@ object SymDenotations {
raw.filterExcluded(excluded).asSeenFrom(pre).toDenot(pre)
}

/** Compute tp.baseTypeRef(this) */
final def baseTypeRefOf(tp: Type)(implicit ctx: Context): Type = {
/** Compute tp.baseType(this) */
final def baseTypeOf(tp: Type)(implicit ctx: Context): Type = {

def foldGlb(bt: Type, ps: List[Type]): Type = ps match {
case p :: ps1 => foldGlb(bt & baseTypeRefOf(p), ps1)
case p :: ps1 => foldGlb(bt & baseTypeOf(p), ps1)
case _ => bt
}

Expand All @@ -1597,7 +1605,7 @@ object SymDenotations {
* and this changes subtyping relations. As a shortcut, we do not
* cache ErasedValueType at all.
*/
def isCachable(tp: Type, btrCache: BaseTypeRefMap): Boolean = {
def isCachable(tp: Type, btrCache: BaseTypeMap): Boolean = {
def inCache(tp: Type) = btrCache.containsKey(tp)
tp match {
case _: TypeErasure.ErasedValueType => false
Expand All @@ -1609,45 +1617,45 @@ object SymDenotations {
}
}

def computeBaseTypeRefOf(tp: Type): Type = {
def computeBaseTypeOf(tp: Type): Type = {
Stats.record("computeBaseTypeOf")
if (symbol.isStatic && tp.derivesFrom(symbol))
if (symbol.isStatic && tp.derivesFrom(symbol) && symbol.typeParams.isEmpty)
symbol.typeRef
else tp match {
case tp: TypeRef =>
case tp: RefType =>
val subcls = tp.symbol
if (subcls eq symbol)
tp
else subcls.denot match {
case cdenot: ClassDenotation =>
if (cdenot.baseClassSet contains symbol) foldGlb(NoType, tp.parents)
if (cdenot.baseClassSet contains symbol) foldGlb(NoType, tp.parentsNEW) // !!! change to parents
else NoType
case _ =>
baseTypeRefOf(tp.superType)
baseTypeOf(tp.superType)
}
case tp: TypeProxy =>
baseTypeRefOf(tp.superType)
baseTypeOf(tp.superType)
case AndType(tp1, tp2) =>
baseTypeRefOf(tp1) & baseTypeRefOf(tp2)
baseTypeOf(tp1) & baseTypeOf(tp2)
case OrType(tp1, tp2) =>
baseTypeRefOf(tp1) | baseTypeRefOf(tp2)
baseTypeOf(tp1) | baseTypeOf(tp2)
case JavaArrayType(_) if symbol == defn.ObjectClass =>
this.typeRef
case _ =>
NoType
}
}

/*>|>*/ ctx.debugTraceIndented(s"$tp.baseTypeRef($this)") /*<|<*/ {
/*>|>*/ ctx.debugTraceIndented(s"$tp.baseType($this)") /*<|<*/ {
tp match {
case tp: CachedType =>
val btrCache = baseTypeRefCache
val btrCache = baseTypeCache
try {
var basetp = btrCache get tp
if (basetp == null) {
btrCache.put(tp, NoPrefix)
basetp = computeBaseTypeRefOf(tp)
if (isCachable(tp, baseTypeRefCache)) btrCache.put(tp, basetp)
basetp = computeBaseTypeOf(tp)
if (isCachable(tp, baseTypeCache)) btrCache.put(tp, basetp)
else btrCache.remove(tp)
} else if (basetp == NoPrefix)
throw CyclicReference(this)
Expand All @@ -1659,7 +1667,7 @@ object SymDenotations {
throw ex
}
case _ =>
computeBaseTypeRefOf(tp)
computeBaseTypeOf(tp)
}
}
}
Expand Down
14 changes: 8 additions & 6 deletions compiler/src/dotty/tools/dotc/core/TypeApplications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ object TypeApplications {
}

def unapply(tp: Type)(implicit ctx: Context): Option[TypeRef] = tp match {
case tp @ HKTypeLambda(tparams, AppliedType(fn: TypeRef, args)) if (args == tparams.map(_.toArg)) => Some(fn)
case tp @ HKTypeLambda(tparams, AnyAppliedType(fn: TypeRef, args)) if (args == tparams.map(_.toArg)) => Some(fn)
case _ => None
}
}
Expand All @@ -87,7 +87,7 @@ object TypeApplications {
*
* where v_i, p_i are the variances and names of the type parameters of T.
*/
object AppliedType {
object AnyAppliedType {
def apply(tp: Type, args: List[Type])(implicit ctx: Context): Type = tp.appliedTo(args)

def unapply(tp: Type)(implicit ctx: Context): Option[(Type, List[Type])] = tp match {
Expand All @@ -111,6 +111,8 @@ object TypeApplications {
None
}
collectArgs(tycon.typeParams, refinements, new mutable.ListBuffer[Type])
case AppliedType(tycon, args) =>
Some((tycon, args))
case HKApply(tycon, args) =>
Some((tycon, args))
case _ =>
Expand Down Expand Up @@ -408,7 +410,7 @@ class TypeApplications(val self: Type) extends AnyVal {
if (!args.exists(_.isInstanceOf[TypeBounds])) {
val followAlias = Config.simplifyApplications && {
dealiased.resType match {
case AppliedType(tyconBody, dealiasedArgs) =>
case AnyAppliedType(tyconBody, dealiasedArgs) =>
// Reduction should not affect type inference when it's
// just eta-reduction (ignoring variance annotations).
// See i2201*.scala for examples where more aggressive
Expand All @@ -421,7 +423,7 @@ class TypeApplications(val self: Type) extends AnyVal {
else HKApply(self, args)
}
else dealiased.resType match {
case AppliedType(tycon, args1) if tycon.safeDealias ne tycon =>
case AnyAppliedType(tycon, args1) if tycon.safeDealias ne tycon =>
// In this case we should always dealias since we cannot handle
// higher-kinded applications to wildcard arguments.
dealiased
Expand Down Expand Up @@ -521,7 +523,7 @@ class TypeApplications(val self: Type) extends AnyVal {
* Existential types in arguments are returned as TypeBounds instances.
*/
final def baseTypeWithArgs(base: Symbol)(implicit ctx: Context): Type = ctx.traceIndented(s"btwa ${self.show} wrt $base", core, show = true) {
def default = self.baseTypeRef(base).appliedTo(baseArgInfos(base))
def default = self.baseTypeTycon(base).appliedTo(baseArgInfos(base))
def isExpandedTypeParam(sym: Symbol) = sym.is(TypeParam) && sym.name.is(ExpandedName)
self match {
case tp: TypeRef =>
Expand Down Expand Up @@ -573,7 +575,7 @@ class TypeApplications(val self: Type) extends AnyVal {
* Existential types in arguments are returned as TypeBounds instances.
*/
final def argInfos(implicit ctx: Context): List[Type] = self match {
case AppliedType(tycon, args) => args
case AnyAppliedType(tycon, args) => args
case _ => Nil
}

Expand Down
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case _ =>
val cls2 = tp2.symbol
if (cls2.isClass) {
val base = tp1.baseTypeRef(cls2)
val base = tp1.baseType(cls2)
if (base.exists && (base ne tp1)) return isSubType(base, tp2)
if (cls2 == defn.SingletonClass && tp1.isStable) return true
}
Expand Down Expand Up @@ -713,7 +713,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
def liftToBase(bcs: List[ClassSymbol]): Boolean = bcs match {
case bc :: bcs1 =>
classBounds.exists(bc.derivesFrom) &&
tyconOK(tp1w.baseTypeRef(bc), tp1w.baseArgInfos(bc)) ||
tyconOK(tp1w.baseTypeTycon(bc), tp1w.baseArgInfos(bc)) ||
liftToBase(bcs1)
case _ =>
false
Expand Down Expand Up @@ -771,7 +771,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
tycon1 match {
case param1: TypeParamRef =>
def canInstantiate = tp2 match {
case AppliedType(tycon2, args2) =>
case AnyAppliedType(tycon2, args2) =>
tryInstantiate(param1, tycon2.ensureHK) && isSubArgs(args1, args2, tycon2.typeParams)
case _ =>
false
Expand Down Expand Up @@ -810,7 +810,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
val classBounds = tp2.classSymbols
def recur(bcs: List[ClassSymbol]): Boolean = bcs match {
case bc :: bcs1 =>
val baseRef = tp1.baseTypeRef(bc)
val baseRef = tp1.baseTypeTycon(bc)
(classBounds.exists(bc.derivesFrom) &&
variancesConform(baseRef.typeParams, tparams) &&
p(baseRef.appliedTo(tp1.baseArgInfos(bc)))
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/core/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
else pre match {
case pre: SuperType => toPrefix(pre.thistpe, cls, thiscls)
case _ =>
if (thiscls.derivesFrom(cls) && pre.baseTypeRef(thiscls).exists) {
if (thiscls.derivesFrom(cls) && pre.baseType(thiscls).exists) { // ??? why not derivesFrom ???
if (theMap != null && theMap.currentVariance <= 0 && !isLegalPrefix(pre)) {
ctx.base.unsafeNonvariant = ctx.runId
pre match {
Expand All @@ -79,7 +79,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
else if ((pre.termSymbol is Package) && !(thiscls is Package))
toPrefix(pre.select(nme.PACKAGE), cls, thiscls)
else
toPrefix(pre.baseTypeRef(cls).normalizedPrefix, cls.owner, thiscls)
toPrefix(pre.baseType(cls).normalizedPrefix, cls.owner, thiscls)
}
}

Expand Down Expand Up @@ -256,7 +256,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
val doms = dominators(commonBaseClasses, Nil)
def baseTp(cls: ClassSymbol): Type = {
val base =
if (tp1.typeParams.nonEmpty) tp.baseTypeRef(cls)
if (tp1.typeParams.nonEmpty) tp.baseTypeTycon(cls)
else tp.baseTypeWithArgs(cls)
base.mapReduceOr(identity)(mergeRefined)
}
Expand Down
Loading