Skip to content

Commit 57e761a

Browse files
committed
Optionally make NamedTypes symbolic
For now it's controlled under a config option.
1 parent eabe551 commit 57e761a

File tree

14 files changed

+179
-132
lines changed

14 files changed

+179
-132
lines changed

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
700700
val tp =
701701
if (sym.isType) {
702702
assert(!sym.is(TypeParam))
703-
TypeRef(tree.tpe, sym.name.asTypeName)
703+
if (config.Config.newScheme) TypeRef.withSym(tree.tpe, sym.asType)
704+
else TypeRef.applyOLD(tree.tpe, sym.name.asTypeName)
704705
}
705706
else
706707
TermRef(tree.tpe, sym.name.asTermName, sym.denot.asSeenFrom(tree.tpe))
@@ -710,7 +711,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
710711
/** A select node with the given selector name and signature and a computed type */
711712
def selectWithSig(name: Name, sig: Signature)(implicit ctx: Context): Tree =
712713
untpd.SelectWithSig(tree, name, sig)
713-
.withType(TermRef(tree.tpe, name.asTermName.withSig(sig)))
714+
.withType(
715+
if (config.Config.newScheme) tree.tpe.select(name.asTermName, sig)
716+
else TermRef.applyOLD(tree.tpe, name.asTermName.withSig(sig)))
714717

715718
/** A select node with selector name and signature taken from `sym`.
716719
* Note: Use this method instead of select(sym) if the referenced symbol

compiler/src/dotty/tools/dotc/config/Config.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ object Config {
148148
final val showCompletions = false
149149

150150
/** If set, enables tracing */
151-
final val tracingEnabled = false
151+
final val tracingEnabled = true
152152

153153
/** Initial capacity of uniques HashMap.
154154
* Note: This MUST BE a power of two to work with util.HashSet
@@ -179,4 +179,6 @@ object Config {
179179

180180
/** When in IDE, turn StaleSymbol errors into warnings instead of crashing */
181181
final val ignoreStaleInIDE = true
182+
183+
val newScheme = false
182184
}

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,10 +1130,12 @@ object SymDenotations {
11301130
def thisType(implicit ctx: Context): Type = NoPrefix
11311131

11321132
override def typeRef(implicit ctx: Context): TypeRef =
1133-
TypeRef(owner.thisType, name.asTypeName, this)
1133+
if (Config.newScheme) TypeRef.withSym(owner.thisType, symbol.asType)
1134+
else TypeRef(owner.thisType, name.asTypeName, this)
11341135

11351136
override def termRef(implicit ctx: Context): TermRef =
1136-
TermRef(owner.thisType, name.asTermName, this)
1137+
if (Config.newScheme) TermRef.withSym(owner.thisType, symbol.asTerm)
1138+
else TermRef(owner.thisType, name.asTermName, this)
11371139

11381140
/** The variance of this type parameter or type member as an Int, with
11391141
* +1 = Covariant, -1 = Contravariant, 0 = Nonvariant, or not a type parameter
@@ -1848,21 +1850,21 @@ object SymDenotations {
18481850
}
18491851
}
18501852

1851-
class NoDenotation(sym: Symbol, name: Name, override val isTerm: Boolean)
1853+
class NoDenotation(sym: Symbol, name: Name, override val exists: Boolean)
18521854
extends SymDenotation(sym, NoSymbol, name, Permanent, NoType) {
1853-
override def exists = false
18541855
override def isType = false
1856+
override def isTerm = exists
18551857
override def owner: Symbol = throw new AssertionError("NoDenotation.owner")
18561858
override def computeAsSeenFrom(pre: Type)(implicit ctx: Context): SingleDenotation = this
18571859
override def mapInfo(f: Type => Type)(implicit ctx: Context): SingleDenotation = this
18581860
validFor = Period.allInRun(NoRunId)
18591861
}
18601862

18611863
@sharable val NoDenotation =
1862-
new NoDenotation(NoSymbol, "<none>".toTermName, isTerm = false)
1864+
new NoDenotation(NoSymbol, "<none>".toTermName, exists = false)
18631865

18641866
@sharable val OverloadedDenotation =
1865-
new NoDenotation(OverloadedSymbol, "<overloaded>".toTermName, isTerm = true)
1867+
new NoDenotation(OverloadedSymbol, "<overloaded>".toTermName, exists = true)
18661868

18671869
// ---- Completion --------------------------------------------------------
18681870

compiler/src/dotty/tools/dotc/core/Symbols.scala

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ trait Symbols { this: Context =>
154154
infoFn(module, modcls), privateWithin)
155155
val mdenot = SymDenotation(
156156
module, owner, name, modFlags | ModuleCreationFlags,
157-
if (cdenot.isCompleted) TypeRef.withSym(owner.thisType, modcls, modclsName)
157+
if (cdenot.isCompleted)
158+
if (config.Config.newScheme) TypeRef.withSym(owner.thisType, modcls)
159+
else TypeRef.withSymOLD(owner.thisType, modcls, modclsName)
158160
else new ModuleCompleter(modcls))
159161
module.denot = mdenot
160162
modcls.denot = cdenot
@@ -179,7 +181,9 @@ trait Symbols { this: Context =>
179181
newModuleSymbol(
180182
owner, name, modFlags, clsFlags,
181183
(module, modcls) => ClassInfo(
182-
owner.thisType, modcls, parents, decls, TermRef.withSym(owner.thisType, module, name)),
184+
owner.thisType, modcls, parents, decls,
185+
if (config.Config.newScheme) TermRef.withSym(owner.thisType, module)
186+
else TermRef.withSymOLD(owner.thisType, module, name)),
183187
privateWithin, coord, assocFile)
184188

185189
val companionMethodFlags = Flags.Synthetic | Flags.Private | Flags.Method
@@ -287,7 +291,10 @@ trait Symbols { this: Context =>
287291
for (name <- names) {
288292
val tparam = newNakedSymbol[TypeName](NoCoord)
289293
tparamBuf += tparam
290-
trefBuf += TypeRef.withSym(owner.thisType, tparam, name)
294+
trefBuf += (
295+
if (config.Config.newScheme) TypeRef.withSym(owner.thisType, tparam)
296+
else TypeRef.withSymOLD(owner.thisType, tparam, name)
297+
)
291298
}
292299
val tparams = tparamBuf.toList
293300
val bounds = boundsFn(trefBuf.toList)
@@ -465,7 +472,7 @@ object Symbols {
465472
*/
466473
final def isReferencedSymbolically(implicit ctx: Context) = {
467474
val d = lastDenot
468-
d != null && (d.is(NonMember) || d.isTerm && ctx.phase.symbolicRefs)
475+
d != null && (d.is(NonMember) || ctx.phase.symbolicRefs)
469476
}
470477

471478
/** Test whether symbol is private. This

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 89 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,11 +1128,21 @@ object Types {
11281128

11291129
/** The type <this . name> , reduced if possible */
11301130
def select(name: Name)(implicit ctx: Context): Type =
1131-
NamedType(this, name).reduceProjection
1131+
if (Config.newScheme) NamedType.withDenot(this, member(name)).reduceProjection
1132+
else NamedType.applyOLD(this, name).reduceProjection
1133+
1134+
def select(name: TermName)(implicit ctx: Context): TermRef =
1135+
if (Config.newScheme) TermRef.withDenot(this, member(name))
1136+
else TermRef.applyOLD(this, name)
1137+
1138+
def select(name: TermName, sig: Signature)(implicit ctx: Context): TermRef = {
1139+
assert(Config.newScheme)
1140+
TermRef.withDenot(this, member(name).atSignature(sig))
1141+
}
11321142

11331143
/** The type <this . name> , reduced if possible, with given denotation if unreduced */
1134-
def select(name: Name, denot: Denotation)(implicit ctx: Context): Type =
1135-
NamedType(this, name, denot).reduceProjection
1144+
def select(name: Name, denot: Denotation)(implicit ctx: Context): Type = // ### drop name
1145+
NamedType.apply(this, name, denot).reduceProjection
11361146

11371147
/** The type <this . name> with either `sym` or its signed name as designator, reduced if possible */
11381148
def select(sym: Symbol)(implicit ctx: Context): Type =
@@ -1616,7 +1626,11 @@ object Types {
16161626
val d = lastDenotation match {
16171627
case null =>
16181628
val sym = lastSymbol
1619-
if (sym != null && sym.isValidInCurrentRun) denotOfSym(sym) else loadDenot
1629+
if (sym != null && sym.isValidInCurrentRun &&
1630+
(!Config.newScheme ||
1631+
(prefix eq NoPrefix) || (prefix eq sym.owner.thisType) || sym.isReferencedSymbolically))
1632+
denotOfSym(sym)
1633+
else loadDenot
16201634
case d: SymDenotation =>
16211635
if (d.validFor.runId == ctx.runId || ctx.stillValid(d))
16221636
if (hasFixedSym)
@@ -1724,8 +1738,10 @@ object Types {
17241738
this
17251739
else if (signature != denot.signature)
17261740
withSig(denot.signature)
1727-
else if (denot.symbol.isPrivate)
1728-
withNameSpace(denot.symbol.owner.typeRef)
1741+
else if (denot.symbol.isPrivate) {
1742+
assert(!Config.newScheme)
1743+
withNameSpaceOLD(denot.symbol.owner.typeRef)
1744+
}
17291745
else
17301746
this
17311747
if (adapted ne this) adapted.withDenot(denot).asInstanceOf[ThisType]
@@ -1766,11 +1782,13 @@ object Types {
17661782
checkedPeriod = Nowhere
17671783
}
17681784

1769-
private def withSig(sig: Signature)(implicit ctx: Context): NamedType =
1770-
TermRef(prefix, designator.withSig(sig))
1785+
private def withSig(sig: Signature)(implicit ctx: Context): NamedType = {
1786+
assert(!Config.newScheme)
1787+
TermRef.applyOLD(prefix, designator.withSig(sig))
1788+
}
17711789

17721790
protected def loadDenot(implicit ctx: Context): Denotation = {
1773-
val d = asMemberOf(prefix, allowPrivate = false)
1791+
val d = asMemberOf(prefix, allowPrivate = Config.newScheme && hasFixedSym)
17741792
def atSig(sig: Signature): Denotation =
17751793
if (sig.ne(Signature.OverloadedSignature)) d.atSignature(sig).checkUnique
17761794
else d
@@ -1945,9 +1963,9 @@ object Types {
19451963

19461964
/** Create a NamedType of the same kind as this type, but with a new namespace.
19471965
*/
1948-
def withNameSpace(nameSpace: NameSpace)(implicit ctx: Context): NamedType =
1966+
def withNameSpaceOLD(nameSpace: NameSpace)(implicit ctx: Context): NamedType =
19491967
if (nameSpace == this.nameSpace) this
1950-
else NamedType(prefix, designator.withNameSpace(nameSpace))
1968+
else NamedType.applyOLD(prefix, designator.withNameSpace(nameSpace))
19511969

19521970
override def equals(that: Any) = that match {
19531971
case that: NamedType =>
@@ -1985,7 +2003,8 @@ object Types {
19852003
override def isOverloaded(implicit ctx: Context) = denot.isOverloaded
19862004

19872005
private def rewrap(sd: SingleDenotation)(implicit ctx: Context) =
1988-
TermRef(prefix, name, sd)
2006+
if (Config.newScheme) TermRef.withDenot(prefix, sd)
2007+
else TermRef.apply(prefix, name, sd)
19892008

19902009
def alternatives(implicit ctx: Context): List[TermRef] =
19912010
denot.alternatives map rewrap
@@ -2019,7 +2038,8 @@ object Types {
20192038
designator.withSig(newSig)
20202039
}
20212040
else designator
2022-
fixDenot(TermRef(prefix, designator1), prefix)
2041+
assert(!Config.newScheme)
2042+
fixDenot(TermRef.applyOLD(prefix, designator1), prefix)
20232043
}
20242044
}
20252045

@@ -2031,7 +2051,8 @@ object Types {
20312051
override def underlying(implicit ctx: Context): Type = info
20322052

20332053
def withPrefix(prefix: Type)(implicit ctx: Context): NamedType =
2034-
TypeRef(prefix, designator)
2054+
if (Config.newScheme) TypeRef(prefix, designator.asInstanceOf[TypeSymbol])
2055+
else TypeRef.applyOLD(prefix, designator)
20352056
}
20362057

20372058
final class CachedTermRef(prefix: Type, designator: TermDesignator, hc: Int) extends TermRef(prefix, designator) {
@@ -2049,12 +2070,19 @@ object Types {
20492070
if (Config.checkUnerased) assert(!ctx.phase.erasedTypes)
20502071

20512072
object NamedType {
2052-
def apply(prefix: Type, designator: Designator)(implicit ctx: Context) =
2073+
def applyOLD(prefix: Type, designator: Designator)(implicit ctx: Context) =
2074+
if (designator.isType) TypeRef.applyOLD(prefix, designator.asType)
2075+
else TermRef.applyOLD(prefix, designator.asTerm)
2076+
def apply(prefix: Type, designator: Symbol)(implicit ctx: Context) =
20532077
if (designator.isType) TypeRef(prefix, designator.asType)
20542078
else TermRef(prefix, designator.asTerm)
2079+
def withDenot(prefix: Type, denot: Denotation)(implicit ctx: Context) =
2080+
if (denot.isTerm) TermRef.withDenot(prefix, denot)
2081+
else TypeRef.withDenot(prefix, denot)
20552082
def apply(prefix: Type, designator: Name, denot: Denotation)(implicit ctx: Context) =
2056-
if (designator.isTermName) TermRef(prefix, designator.asTermName, denot)
2057-
else TypeRef(prefix, designator.asTypeName, denot)
2083+
if (Config.newScheme) withDenot(prefix, denot)
2084+
else if (designator.isTermName) TermRef.apply(prefix, designator.asTermName, denot)
2085+
else TypeRef.apply(prefix, designator.asTypeName, denot)
20582086
def withSym(prefix: Type, sym: Symbol)(implicit ctx: Context): NamedType =
20592087
if (sym.isType) TypeRef.withSym(prefix, sym.asType)
20602088
else TermRef.withSym(prefix, sym.asTerm)
@@ -2066,58 +2094,73 @@ object Types {
20662094
* Its meaning is the (potentially multi-) denotation of the member(s)
20672095
* of prefix with given name.
20682096
*/
2069-
def apply(prefix: Type, designator: TermDesignator)(implicit ctx: Context): TermRef =
2097+
def applyOLD(prefix: Type, designator: TermDesignator)(implicit ctx: Context): TermRef =
2098+
ctx.uniqueNamedTypes.enterIfNew(prefix, designator, isTerm = true).asInstanceOf[TermRef]
2099+
2100+
def apply(prefix: Type, designator: TermSymbol)(implicit ctx: Context): TermRef =
20702101
ctx.uniqueNamedTypes.enterIfNew(prefix, designator, isTerm = true).asInstanceOf[TermRef]
20712102

20722103
/** Create term ref to given initial denotation, taking the signature
20732104
* from the denotation if it is completed, or creating a term ref without
20742105
* signature, if denotation is not yet completed.
20752106
*/
20762107
def apply(prefix: Type, name: TermName, denot: Denotation)(implicit ctx: Context): TermRef = {
2077-
if ((prefix eq NoPrefix) || denot.symbol.isReferencedSymbolically) apply(prefix, denot.symbol.asTerm)
2108+
if (Config.newScheme) withDenot(prefix, denot)
2109+
else if ((prefix eq NoPrefix) || denot.symbol.isReferencedSymbolically) apply(prefix, denot.symbol.asTerm)
20782110
else denot match {
20792111
case denot: SingleDenotation =>
2080-
apply(prefix, name.withSig(denot.signature).localizeIfPrivate(denot.symbol))
2081-
case _ => apply(prefix, name)
2112+
applyOLD(prefix, name.withSig(denot.signature).localizeIfPrivate(denot.symbol))
2113+
case _ => applyOLD(prefix, name)
20822114
}
20832115
} withDenot denot
20842116

2117+
def withDenot(prefix: Type, denot: Denotation)(implicit ctx: Context): TermRef =
2118+
apply(prefix, denot.symbol.asTerm).withDenot(denot)
2119+
20852120
/** Create a term ref referring to given symbol with given name.
20862121
* This is similar to TermRef(Type, Symbol), except:
20872122
* (1) the symbol might not yet have a denotation, so the name needs to be given explicitly.
20882123
* (2) the designator of the TermRef is either the symbol or its name & unforced signature.
20892124
*/
2090-
def withSym(prefix: Type, sym: TermSymbol, name: TermName)(implicit ctx: Context): TermRef =
2125+
def withSymOLD(prefix: Type, sym: TermSymbol, name: TermName)(implicit ctx: Context): TermRef =
20912126
if ((prefix eq NoPrefix) || sym.isReferencedSymbolically) apply(prefix, sym)
2092-
else apply(prefix, name.withSig(sym.signature).localizeIfPrivate(sym)).withSym(sym)
2127+
else applyOLD(prefix, name.withSig(sym.signature).localizeIfPrivate(sym)).withSym(sym)
20932128

20942129
def withSym(prefix: Type, sym: TermSymbol)(implicit ctx: Context): TermRef =
2095-
withSym(prefix, sym, sym.name)
2130+
if (Config.newScheme) apply(prefix, sym) else withSymOLD(prefix, sym, sym.name)
20962131
}
20972132

20982133
object TypeRef {
20992134

21002135
/** Create type ref with given prefix and name */
2101-
def apply(prefix: Type, desig: TypeDesignator)(implicit ctx: Context): TypeRef =
2136+
def applyOLD(prefix: Type, desig: TypeDesignator)(implicit ctx: Context): TypeRef =
2137+
ctx.uniqueNamedTypes.enterIfNew(prefix, desig, isTerm = false).asInstanceOf[TypeRef]
2138+
2139+
/** Create type ref with given prefix and name */
2140+
def apply(prefix: Type, desig: TypeSymbol)(implicit ctx: Context): TypeRef =
21022141
ctx.uniqueNamedTypes.enterIfNew(prefix, desig, isTerm = false).asInstanceOf[TypeRef]
21032142

21042143
/** Create a type ref with given name and initial denotation */
21052144
def apply(prefix: Type, name: TypeName, denot: Denotation)(implicit ctx: Context): TypeRef = {
2106-
if ((prefix eq NoPrefix) || denot.symbol.isReferencedSymbolically) apply(prefix, denot.symbol.asType)
2107-
else apply(prefix, name.localizeIfPrivate(denot.symbol))
2145+
if (Config.newScheme) withDenot(prefix, denot)
2146+
else if ((prefix eq NoPrefix) || denot.symbol.isReferencedSymbolically) apply(prefix, denot.symbol.asType)
2147+
else applyOLD(prefix, name.localizeIfPrivate(denot.symbol))
21082148
} withDenot denot
21092149

2150+
def withDenot(prefix: Type, denot: Denotation)(implicit ctx: Context): TypeRef =
2151+
apply(prefix, denot.symbol.asType).withDenot(denot)
2152+
21102153
/** Create a type ref referring to either a given symbol or its name.
21112154
* This is similar to TypeRef(prefix, sym), except:
21122155
* (1) the symbol might not yet have a denotation, so the name needs to be given explicitly.
21132156
* (2) the designator of the TypeRef is either the symbol or its name
21142157
*/
2115-
def withSym(prefix: Type, sym: TypeSymbol, name: TypeName)(implicit ctx: Context): TypeRef =
2158+
def withSymOLD(prefix: Type, sym: TypeSymbol, name: TypeName)(implicit ctx: Context): TypeRef =
21162159
if ((prefix eq NoPrefix) || sym.isReferencedSymbolically) apply(prefix, sym)
2117-
else apply(prefix, name.localizeIfPrivate(sym)).withSym(sym)
2160+
else applyOLD(prefix, name.localizeIfPrivate(sym)).withSym(sym)
21182161

21192162
def withSym(prefix: Type, sym: TypeSymbol)(implicit ctx: Context): TypeRef =
2120-
withSym(prefix, sym, sym.name)
2163+
if (Config.newScheme) apply(prefix, sym) else withSymOLD(prefix, sym, sym.name)
21212164
}
21222165

21232166
// --- Other SingletonTypes: ThisType/SuperType/ConstantType ---------------------------
@@ -3445,7 +3488,8 @@ object Types {
34453488
if (appliedRefCache == null) {
34463489
val tref =
34473490
if ((cls is PackageClass) || cls.owner.isTerm) symbolicTypeRef // ??? not always symbolicRef
3448-
else TypeRef(prefix, cls.name, clsDenot)
3491+
else if (Config.newScheme) TypeRef.withDenot(prefix, clsDenot)
3492+
else TypeRef.apply(prefix, cls.name, clsDenot)
34493493
appliedRefCache =
34503494
tref.appliedTo(cls.typeParams.map(_.typeRef))
34513495
}
@@ -3527,7 +3571,20 @@ object Types {
35273571
case tp: ClassInfo =>
35283572
// Note: Taking a normal typeRef does not work here. A normal ref might contain
35293573
// also other information about the named type (e.g. bounds).
3530-
contains(tp.symbolicTypeRef) // ??? not clear
3574+
if (Config.newScheme) {
3575+
val loOK =
3576+
lo.isRef(tp.cls) ||
3577+
lo.isRef(defn.NothingClass) ||
3578+
lo.isRef(defn.NullClass) && !tp.cls.isValueClass
3579+
val hiOK =
3580+
hi.isRef(tp.cls) ||
3581+
tp.parents.exists(p => p <:< hi)
3582+
loOK && hiOK || {
3583+
println(i"NOT CONTAINS: $this / $tp")
3584+
false
3585+
}
3586+
}
3587+
else contains(tp.symbolicTypeRef)
35313588
case _ => lo <:< tp && tp <:< hi
35323589
}
35333590

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,10 @@ class ClassfileParser(
319319
case 'L' =>
320320
def processInner(tp: Type): Type = tp match {
321321
case tp: TypeRef if !(tp.symbol.owner is Flags.ModuleClass) =>
322-
TypeRef.withSym(processInner(tp.prefix.widen), tp.symbol.asType, tp.name)
322+
if (config.Config.newScheme)
323+
TypeRef.withSym(processInner(tp.prefix.widen), tp.symbol.asType)
324+
else
325+
TypeRef.withSymOLD(processInner(tp.prefix.widen), tp.symbol.asType, tp.name)
323326
case _ =>
324327
tp
325328
}

0 commit comments

Comments
 (0)