Skip to content

Commit 653d8b4

Browse files
committed
Make Symbol inherit from SymDenotation
Avoids having two objects for symbols at typer
1 parent 41c4ae3 commit 653d8b4

File tree

3 files changed

+101
-48
lines changed

3 files changed

+101
-48
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ object Denotations {
582582
*/
583583
def prefix: Type = NoPrefix
584584

585-
final def signature(using Context): Signature =
585+
def signature(using Context): Signature =
586586
if (isType) Signature.NotAMethod // don't force info if this is a type SymDenotation
587587
else info match {
588588
case info: MethodicType =>

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import ast._
1515
import ast.Trees.{LambdaTypeTree, TypeBoundsTree, ValDef, TypeDef}
1616
import Trees.Literal
1717
import Variances.Variance
18-
import annotation.tailrec
18+
import annotation.{tailrec, threadUnsafe}
1919
import util.SimpleIdentityMap
2020
import util.Stats
2121
import java.util.WeakHashMap
@@ -34,15 +34,17 @@ object SymDenotations {
3434
*/
3535
class SymDenotation private[core] (
3636
_symbol: SymbolImpl,
37-
final val _maybeOwner: SymbolImpl,
37+
_maybeOwner: SymbolImpl,
3838
final val name: Name,
3939
initFlags: FlagSet,
4040
initInfo: Type,
4141
initPrivateWithin: SymbolImpl = NoSymbol.toSymbolImpl) extends SingleDenotation(_symbol, initInfo) {
4242

4343
//assert(symbol.id != 4940, name)
4444

45-
final val maybeOwner: Symbol = _maybeOwner.fromSymbolImpl
45+
val maybeOwner: Symbol =
46+
if _maybeOwner == null then this.asInstanceOf[Symbol]
47+
else _maybeOwner.fromSymbolImpl
4648

4749
override def hasUniqueSym: Boolean = exists
4850

@@ -1471,7 +1473,8 @@ object SymDenotations {
14711473
else if myFlags.is(Method) then "method"
14721474
else "val"
14731475

1474-
override def toString: String = s"$kindString $name"
1476+
def denotString: String = s"$kindString $name"
1477+
override def toString: String = denotString
14751478

14761479
// ----- Sanity checks and debugging */
14771480

@@ -2393,8 +2396,9 @@ object SymDenotations {
23932396
ClassDenotationImpl(_symbol, _maybeOwner, name, initFlags, initInfo, initPrivateWithin),
23942397
PackageClassDenotation
23952398

2396-
@sharable object NoDenotation
2397-
extends SymDenotation(NoSymbol.toSymbolImpl, NoSymbol.toSymbolImpl, "<none>".toTermName, Permanent, NoType) {
2399+
@sharable @threadUnsafe lazy val NoDenotation: SymDenotation = NoSymbol.toSymbolImpl
2400+
2401+
/* extends SymDenotation(NoSymbol.toSymbolImpl, NoSymbol.toSymbolImpl, "<none>".toTermName, Permanent, NoType) {
23982402
override def isType: Boolean = false
23992403
override def isTerm: Boolean = false
24002404
override def exists: Boolean = false
@@ -2411,7 +2415,7 @@ object SymDenotations {
24112415
24122416
NoSymbol.denot = this
24132417
validFor = Period.allInRun(NoRunId)
2414-
}
2418+
}*/
24152419

24162420
/** Can a private symbol with given name and flags be inferred to be local,
24172421
* if all references to such symbols are via `this`?

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

Lines changed: 89 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ object Symbols:
108108
def asType(using Context): TypeSymbol
109109

110110
def isClass: Boolean
111+
@targetName("Symbol_asClass")
111112
def asClass: ClassSymbol
112113

113114
def isPrivate(using Context): Boolean
@@ -179,8 +180,17 @@ object Symbols:
179180
* @param coord The coordinates of the symbol (a position or an index)
180181
* @param id A unique identifier of the symbol (unique per ContextBase)
181182
*/
182-
class SymbolImpl private[Symbols] (private var myCoord: Coord, val id: Int)
183-
extends SymbolDecl {
183+
class SymbolImpl private[Symbols] (
184+
maybeOwner: SymbolImpl,
185+
name: Name,
186+
initFlags: FlagSet,
187+
initInfo: Type,
188+
initPrivateWithin: SymbolImpl,
189+
private var myCoord: Coord,
190+
val id: Int)
191+
extends
192+
SymDenotation(null, maybeOwner, name, initFlags, initInfo, initPrivateWithin),
193+
SymbolDecl {
184194

185195
type ThisName <: Name
186196

@@ -234,6 +244,8 @@ object Symbols:
234244
checkedPeriod = Nowhere
235245
}
236246

247+
denot = this
248+
237249
/** The current denotation of this symbol */
238250
final def denot(using Context): SymDenotation = {
239251
util.Stats.record("Symbol.denot")
@@ -305,9 +317,8 @@ object Symbols:
305317
asInstanceOf[TypeSymbol]
306318
}
307319

308-
final def isClass: Boolean = isInstanceOf[ClassSymbol @unchecked]
309-
310-
final def asClass: ClassSymbol = asInstanceOf[ClassSymbol]
320+
@targetName("Symbol_asClass")
321+
override def asClass: ClassSymbol = asInstanceOf[ClassSymbol]
311322

312323
/** Test whether symbol is private. This
313324
* conservatively returns `false` if symbol does not yet have a denotation, or denotation
@@ -324,15 +335,14 @@ object Symbols:
324335
!isClass && this.is(Case, butNot = Enum | Module)
325336

326337
/** The symbol's signature if it is completed or a method, NotAMethod otherwise. */
327-
final def signature(using Context): Signature =
328-
if (lastDenot != null && (lastDenot.isCompleted || lastDenot.is(Method)))
329-
denot.signature
330-
else
331-
Signature.NotAMethod
332-
338+
final override def signature(using Context): Signature =
339+
if denot eq this then super.signature
340+
else denot.signature
341+
/*
333342
/** Special cased here, because it may be used on naked symbols in substituters */
334343
final def isStatic(using Context): Boolean =
335344
lastDenot != null && lastDenot.initial.isStatic
345+
*/
336346

337347
/** This symbol entered into owner's scope (owner must be a class). */
338348
final def entered(using Context): this.type = {
@@ -387,16 +397,15 @@ object Symbols:
387397
def filter(p: Symbol => Boolean): Symbol = if (p(this.fromSymbolImpl)) this.fromSymbolImpl else NoSymbol
388398

389399
/** The current name of this symbol */
390-
final def name(using Context): ThisName = denot.name.asInstanceOf[ThisName]
400+
override def name(using Context): ThisName = denot.name.asInstanceOf[ThisName]
391401

392402
/** The source or class file from which this class or
393403
* the class containing this symbol was generated, null if not applicable.
394404
* Note that this the returned classfile might be the top-level class
395405
* containing this symbol instead of the directly enclosing class.
396406
* Overridden in ClassSymbol
397407
*/
398-
def associatedFile(using Context): AbstractFile =
399-
if (lastDenot == null) null else lastDenot.topLevelClass.associatedFile
408+
def associatedFile(using Context): AbstractFile = topLevelClass.associatedFile
400409

401410
/** The class file from which this class was generated, null if not applicable. */
402411
final def binaryFile(using Context): AbstractFile = {
@@ -485,22 +494,33 @@ object Symbols:
485494

486495
override def toString: String =
487496
if (lastDenot == null) s"Naked$prefixString#$id"
488-
else lastDenot.toString// + "#" + id // !!! DEBUG
497+
else lastDenot.denotString// + "#" + id // !!! DEBUG
489498

490-
def toText(printer: Printer): Text = printer.toText(this.fromSymbolImpl)
499+
override def toText(printer: Printer): Text = printer.toText(this.fromSymbolImpl)
491500

492501
def showLocated(using Context): String = ctx.printer.locatedText(this.fromSymbolImpl).show
493502
def showExtendedLocation(using Context): String = ctx.printer.extendedLocationText(this.fromSymbolImpl).show
494-
def showDcl(using Context): String = ctx.printer.dclText(this.fromSymbolImpl).show
503+
override def showDcl(using Context): String = ctx.printer.dclText(this.fromSymbolImpl).show
495504
def showKind(using Context): String = ctx.printer.kindString(this.fromSymbolImpl)
496505
def showName(using Context): String = ctx.printer.nameString(this.fromSymbolImpl)
497506
def showFullName(using Context): String = ctx.printer.fullNameString(this.fromSymbolImpl)
498507

499508
override def hashCode(): Int = id // for debugging.
500509
}
501510

502-
class ClassSymbolImpl private[Symbols] (coord: Coord, val assocFile: AbstractFile, id: Int)
503-
extends SymbolImpl(coord, id), ClassSymbolDecl {
511+
class ClassSymbolImpl private[Symbols] (
512+
maybeOwner: SymbolImpl,
513+
name: Name,
514+
initFlags: FlagSet,
515+
initInfo: Type,
516+
initPrivateWithin: SymbolImpl,
517+
initCoord: Coord,
518+
val assocFile: AbstractFile,
519+
id: Int)
520+
extends SymbolImpl(
521+
maybeOwner, name, initFlags, initInfo, initPrivateWithin, initCoord, id),
522+
ClassSymbolDecl,
523+
ClassDenotation {
504524

505525
type ThisName = TypeName
506526

@@ -591,14 +611,44 @@ object Symbols:
591611
}
592612

593613
/** Kept separate since it keeps only PackageClassDenotation */
594-
class PackageClassSymbolImpl(id: Int) extends ClassSymbolImpl(NoCoord, null, id)
614+
class PackageClassSymbolImpl private[Symbols] (
615+
maybeOwner: SymbolImpl,
616+
name: Name,
617+
initFlags: FlagSet,
618+
initInfo: Type,
619+
initPrivateWithin: SymbolImpl,
620+
id: Int)
621+
extends ClassSymbolImpl(
622+
maybeOwner, name, initFlags, initInfo, initPrivateWithin, NoCoord, null, id),
623+
PackageClassDenotation
595624

596625
@sharable
597-
val NoSymbol: Symbol = new SymbolImpl(NoCoord, 0) {
598-
override def associatedFile(using Context): AbstractFile = NoSource.file
599-
override def recomputeDenot(lastd: SymDenotation)(using Context): SymDenotation = NoDenotation
600-
}.fromSymbolImpl
601-
NoDenotation // force it in order to set `denot` field of NoSymbol
626+
val NoSymbol: Symbol = new SymbolImpl(
627+
null, "<none>".toTermName, Permanent, NoType, null, NoCoord, 0):
628+
629+
override def isType: Boolean = false
630+
override def isTerm: Boolean = false
631+
override def exists: Boolean = false
632+
override def owner: Symbol = throw new AssertionError("NoDenotation.owner")
633+
override def computeAsSeenFrom(pre: Type)(using Context): SingleDenotation = this
634+
override def mapInfo(f: Type => Type)(using Context): SingleDenotation = this
635+
636+
override def matches(other: SingleDenotation)(using Context): Boolean = false
637+
override def targetName(using Context): Name = EmptyTermName
638+
override def mapInherited(ownDenots: PreDenotation, prevDenots: PreDenotation, pre: Type)(using Context): SingleDenotation = this
639+
override def filterWithPredicate(p: SingleDenotation => Boolean): SingleDenotation = this
640+
override def filterDisjoint(denots: PreDenotation)(using Context): SingleDenotation = this
641+
override def filterWithFlags(required: FlagSet, excluded: FlagSet)(using Context): SingleDenotation = this
642+
643+
validFor = Period.allInRun(NoRunId)
644+
645+
override def associatedFile(using Context): AbstractFile = NoSource.file
646+
647+
override def recomputeDenot(lastd: SymDenotation)(using Context): SymDenotation =
648+
NoDenotation
649+
.fromSymbolImpl
650+
651+
// NoDenotation // force it in order to set `denot` field of NoSymbol
602652

603653
extension [N <: Name](sym: Symbol { type ThisName = N })(using Context) {
604654
/** Copy a symbol, overriding selective fields.
@@ -653,12 +703,11 @@ object Symbols:
653703
flags: FlagSet,
654704
info: Type,
655705
privateWithin: Symbol = NoSymbol,
656-
coord: Coord = NoCoord)(using Context): Symbol { type ThisName = N } = {
657-
val sym = new SymbolImpl(coord, ctx.base.nextSymId).asInstanceOf[Symbol { type ThisName = N }]
658-
val denot = SymDenotation(sym, owner, name, flags, info, privateWithin)
659-
sym.denot = denot
660-
sym
661-
}
706+
coord: Coord = NoCoord)(using Context): Symbol { type ThisName = N } =
707+
val symi = new SymbolImpl(
708+
owner.toSymbolImpl, name, flags, info, privateWithin.toSymbolImpl, coord, ctx.base.nextSymId)
709+
symi.validFor = currentStablePeriod
710+
symi.asInstanceOf[Symbol { type ThisName = N }]
662711

663712
/** Create a class symbol from its non-info fields and a function
664713
* producing its info (the produced info may be lazy).
@@ -670,18 +719,18 @@ object Symbols:
670719
infoFn: ClassSymbol => Type,
671720
privateWithin: Symbol = NoSymbol,
672721
coord: Coord = NoCoord,
673-
assocFile: AbstractFile = null)(using Context): ClassSymbol
674-
= {
675-
val cls = (
722+
assocFile: AbstractFile = null)(using Context): ClassSymbol =
723+
val clsi =
676724
if flags.is(Package) then
677-
new PackageClassSymbolImpl(ctx.base.nextSymId)
725+
new PackageClassSymbolImpl(
726+
owner.toSymbolImpl, name, flags, NoCompleter, privateWithin.toSymbolImpl, ctx.base.nextSymId)
678727
else
679-
new ClassSymbolImpl(coord, assocFile, ctx.base.nextSymId)
680-
).fromSymbolImpl.asClass
681-
val denot = SymDenotation(cls, owner, name, flags, infoFn(cls), privateWithin)
682-
cls.denot = denot
728+
new ClassSymbolImpl(
729+
owner.toSymbolImpl, name, flags, NoCompleter, privateWithin.toSymbolImpl, coord, assocFile, ctx.base.nextSymId)
730+
clsi.validFor = currentStablePeriod
731+
val cls = clsi.fromSymbolImpl.asClass
732+
cls.info = infoFn(cls)
683733
cls
684-
}
685734

686735
/** Create a class symbol from its non-info fields and the fields of its info. */
687736
def newCompleteClassSymbol(

0 commit comments

Comments
 (0)