aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r--src/dotty/tools/dotc/core/Decorators.scala36
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala12
-rw-r--r--src/dotty/tools/dotc/core/DenotTransformers.scala8
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala59
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala36
-rw-r--r--src/dotty/tools/dotc/core/NameOps.scala21
-rw-r--r--src/dotty/tools/dotc/core/Periods.scala7
-rw-r--r--src/dotty/tools/dotc/core/Phases.scala18
-rw-r--r--src/dotty/tools/dotc/core/Scopes.scala9
-rw-r--r--src/dotty/tools/dotc/core/Signature.scala2
-rw-r--r--src/dotty/tools/dotc/core/Substituters.scala6
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala88
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala6
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala34
-rw-r--r--src/dotty/tools/dotc/core/Types.scala57
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala20
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala16
-rw-r--r--src/dotty/tools/dotc/core/transform/Erasure.scala2
18 files changed, 322 insertions, 115 deletions
diff --git a/src/dotty/tools/dotc/core/Decorators.scala b/src/dotty/tools/dotc/core/Decorators.scala
index 155ea87e0..cd7b46896 100644
--- a/src/dotty/tools/dotc/core/Decorators.scala
+++ b/src/dotty/tools/dotc/core/Decorators.scala
@@ -143,7 +143,7 @@ object Decorators {
* 2) Lists can be formatted using the desired separator between two `%` signs,
* eg `i"myList = (${myList}%, %)"`
*/
- implicit class InfoString(val sc: StringContext) extends AnyVal {
+ implicit class StringInterpolators(val sc: StringContext) extends AnyVal {
def i(args: Any*)(implicit ctx: Context): String = {
@@ -166,7 +166,39 @@ object Decorators {
val (args1, suffixes1) = (args, suffixes).zipped.map(treatArg(_, _)).unzip
new StringContext(prefix :: suffixes1.toList: _*).s(args1: _*)
}
- }
+ /** Lifted from scala.reflect.internal.util
+ * A safe combination of [[scala.collection.immutable.StringLike#stripMargin]]
+ * and [[scala.StringContext#raw]].
+ *
+ * The margin of each line is defined by whitespace leading up to a '|' character.
+ * This margin is stripped '''before''' the arguments are interpolated into to string.
+ *
+ * String escape sequences are '''not''' processed; this interpolater is designed to
+ * be used with triple quoted Strings.
+ *
+ * {{{
+ * scala> val foo = "f|o|o"
+ * foo: String = f|o|o
+ * scala> sm"""|${foo}
+ * |"""
+ * res0: String =
+ * "f|o|o
+ * "
+ * }}}
+ */
+ final def sm(args: Any*): String = {
+ def isLineBreak(c: Char) = c == '\n' || c == '\f' // compatible with StringLike#isLineBreak
+ def stripTrailingPart(s: String) = {
+ val (pre, post) = s.span(c => !isLineBreak(c))
+ pre + post.stripMargin
+ }
+ val stripped: List[String] = sc.parts.toList match {
+ case head :: tail => head.stripMargin :: (tail map stripTrailingPart)
+ case Nil => Nil
+ }
+ new StringContext(stripped: _*).raw(args: _*)
+ }
+ }
}
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 5e335e240..594f0c013 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -37,7 +37,7 @@ class Definitions {
scope.enter(newSymbol(cls, name, flags, TypeBounds.empty))
private def newTypeParam(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
- newTypeField(cls, name, flags | TypeParamCreationFlags, scope)
+ newTypeField(cls, name, flags | ClassTypeParamCreationFlags, scope)
private def newSyntheticTypeParam(cls: ClassSymbol, scope: MutableScope, paramFlags: FlagSet, suffix: String = "T0") =
newTypeParam(cls, suffix.toTypeName.expandedName(cls), ExpandedName | paramFlags, scope)
@@ -409,20 +409,20 @@ class Definitions {
lazy val RootImports = List[Symbol](JavaLangPackageVal, ScalaPackageVal, ScalaPredefModule, DottyPredefModule)
- def isTupleType(tp: Type) = {
+ def isTupleType(tp: Type)(implicit ctx: Context) = {
val arity = tp.dealias.argInfos.length
arity <= MaxTupleArity && (tp isRef TupleClass(arity))
}
- def isProductSubType(tp: Type) =
+ def isProductSubType(tp: Type)(implicit ctx: Context) =
(tp derivesFrom ProductClass) && tp.baseClasses.exists(ProductClasses contains _)
- def isFunctionType(tp: Type) = {
+ def isFunctionType(tp: Type)(implicit ctx: Context) = {
val arity = functionArity(tp)
0 <= arity && arity <= MaxFunctionArity && (tp isRef FunctionClass(arity))
}
- def functionArity(tp: Type) = tp.dealias.argInfos.length - 1
+ def functionArity(tp: Type)(implicit ctx: Context) = tp.dealias.argInfos.length - 1
// ----- LambdaXYZ traits ------------------------------------------
@@ -544,7 +544,7 @@ class Definitions {
val BooleanEnc = 17
val UnitEnc = 19
- def isValueSubClass(cls1: Symbol, cls2: Symbol) =
+ def isValueSubClass(cls1: Symbol, cls2: Symbol)(implicit ctx: Context) =
valueClassEnc(cls2) % valueClassEnc(cls1) == 0
// ----- Initialization ---------------------------------------------------
diff --git a/src/dotty/tools/dotc/core/DenotTransformers.scala b/src/dotty/tools/dotc/core/DenotTransformers.scala
index 6daa028fc..e052a07ea 100644
--- a/src/dotty/tools/dotc/core/DenotTransformers.scala
+++ b/src/dotty/tools/dotc/core/DenotTransformers.scala
@@ -46,4 +46,12 @@ object DenotTransformers {
}
}
}
+
+ /** A `DenotTransformer` trait that has the identity as its `transform` method.
+ * You might want to inherit from this trait so that new denotations can be
+ * installed using `installAfter` and `enteredAfter` at the end of the phase.
+ */
+ trait IdentityDenotTransformer extends DenotTransformer {
+ def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref
+ }
}
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 264f9aa46..43fff62ec 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -375,7 +375,7 @@ object Denotations {
final def signature(implicit ctx: Context): Signature = {
if (isType) Signature.NotAMethod // don't force info if this is a type SymDenotation
else info match {
- case info: SignedType =>
+ case info: MethodicType =>
try info.signature
catch { // !!! DEBUG
case ex: Throwable =>
@@ -494,7 +494,8 @@ object Denotations {
} while (d ne denot)
initial.syncWithParents
case _ =>
- staleSymbolError
+ if (coveredInterval.containsPhaseId(ctx.phaseId)) staleSymbolError
+ else NoDenotation
}
/** Produce a denotation that is valid for the given context.
@@ -512,7 +513,13 @@ object Denotations {
def current(implicit ctx: Context): SingleDenotation = {
val currentPeriod = ctx.period
val valid = myValidFor
- assert(valid.code > 0)
+ if (valid.code <= 0) {
+ // can happen if we sit on a stale denotation which has been replaced
+ // wholesale by an installAfter; in this case, proceed to the next
+ // denotation and try again.
+ if (validFor == Nowhere && nextInRun.validFor != Nowhere) return nextInRun.current
+ assert(false)
+ }
if (valid.runId != currentPeriod.runId) bringForward.current
else {
@@ -551,6 +558,7 @@ object Denotations {
cur = next
}
cur.validFor = Period(currentPeriod.runId, startPid, transformer.lastPhaseId)
+ //printPeriods(cur)
//println(s"new denot: $cur, valid for ${cur.validFor}")
}
cur.current // multiple transformations could be required
@@ -563,23 +571,28 @@ object Denotations {
//println(s"searching: $cur at $currentPeriod, valid for ${cur.validFor}")
cur = cur.nextInRun
cnt += 1
- assert(cnt <= MaxPossiblePhaseId, s"seems to be a loop in Denotations for $this, currentPeriod = $currentPeriod")
+ assert(cnt <= MaxPossiblePhaseId, demandOutsideDefinedMsg)
}
cur
}
-
}
}
+ private def demandOutsideDefinedMsg(implicit ctx: Context): String =
+ s"demanding denotation of $this at phase ${ctx.phase}(${ctx.phaseId}) outside defined interval: defined periods are${definedPeriodsString}"
+
/** Install this denotation to be the result of the given denotation transformer.
* This is the implementation of the same-named method in SymDenotations.
* It's placed here because it needs access to private fields of SingleDenotation.
+ * @pre Can only be called in `phase.next`.
*/
protected def installAfter(phase: DenotTransformer)(implicit ctx: Context): Unit = {
val targetId = phase.next.id
assert(ctx.phaseId == targetId,
s"denotation update for $this called in phase ${ctx.phase}, expected was ${phase.next}")
val current = symbol.current
+ // println(s"installing $this after $phase/${phase.id}, valid = ${current.validFor}")
+ // printPeriods(current)
this.nextInRun = current.nextInRun
this.validFor = Period(ctx.runId, targetId, current.validFor.lastPhaseId)
if (current.validFor.firstPhaseId == targetId) {
@@ -587,12 +600,14 @@ object Denotations {
var prev = current
while (prev.nextInRun ne current) prev = prev.nextInRun
prev.nextInRun = this
+ current.validFor = Nowhere
}
else {
// insert this denotation after current
current.validFor = Period(ctx.runId, current.validFor.firstPhaseId, targetId - 1)
current.nextInRun = this
}
+ // printPeriods(this)
}
def staleSymbolError(implicit ctx: Context) = {
@@ -604,6 +619,22 @@ object Denotations {
throw new StaleSymbol(msg)
}
+ /** The period (interval of phases) for which there exists
+ * a valid denotation in this flock.
+ */
+ def coveredInterval(implicit ctx: Context): Period = {
+ var cur = this
+ var cnt = 0
+ var interval = validFor
+ do {
+ cur = cur.nextInRun
+ cnt += 1
+ assert(cnt <= MaxPossiblePhaseId, demandOutsideDefinedMsg)
+ interval |= cur.validFor
+ } while (cur ne this)
+ interval
+ }
+
/** For ClassDenotations only:
* If caches influenced by parent classes are still valid, the denotation
* itself, otherwise a freshly initialized copy.
@@ -614,10 +645,24 @@ object Denotations {
if (symbol == NoSymbol) symbol.toString
else s"<SingleDenotation of type $infoOrCompleter>"
+
+ def definedPeriodsString: String = {
+ var sb = new StringBuilder()
+ var cur = this
+ var cnt = 0
+ do {
+ sb.append(" " + cur.validFor)
+ cur = cur.nextInRun
+ cnt += 1
+ if (cnt > MaxPossiblePhaseId) { sb.append(" ..."); cur = this }
+ } while (cur ne this)
+ sb.toString
+ }
+
// ------ PreDenotation ops ----------------------------------------------
final def first = this
- final def toDenot(pre: Type)(implicit ctx: Context) = this
+ final def toDenot(pre: Type)(implicit ctx: Context): Denotation = this
final def containsSym(sym: Symbol): Boolean = hasUniqueSym && (symbol eq sym)
final def containsSig(sig: Signature)(implicit ctx: Context) =
exists && (signature matches sig)
@@ -764,7 +809,7 @@ object Denotations {
else DenotUnion(this, that)
}
- case class DenotUnion(denots1: PreDenotation, denots2: PreDenotation) extends PreDenotation {
+ final case class DenotUnion(denots1: PreDenotation, denots2: PreDenotation) extends PreDenotation {
assert(denots1.exists && denots2.exists, s"Union of non-existing denotations ($denots1) and ($denots2)")
def exists = true
def first = denots1.first
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index 40da7525d..c467a553f 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -102,8 +102,16 @@ object Flags {
}
/** The list of non-empty names of flags that are set in this FlagSet */
- def flagStrings: Seq[String] =
- (2 to MaxFlag).flatMap(flagString)
+ def flagStrings: Seq[String] = {
+ val rawStrings = (2 to MaxFlag).flatMap(flagString)
+ if (this is Local)
+ rawStrings.filter(_ != "<local>").map {
+ case "private" => "private[this]"
+ case "protected" => "protected[this]"
+ case str => str
+ }
+ else rawStrings
+ }
/** The string representation of this flag set */
override def toString = flagStrings.mkString(" ")
@@ -316,8 +324,8 @@ object Flags {
/** Symbol is initialized to the default value, e.g. var x: T = _ */
final val DefaultInit = termFlag(29, "<defaultinit>")
- /** Symbol is a macro */
- final val Macro = commonFlag(30, "<macro>")
+ /** Symbol is inlined */
+ final val Inline = commonFlag(30, "inline")
/** Symbol is defined by a Java class */
final val JavaDefined = commonFlag(31, "<java>")
@@ -387,14 +395,17 @@ object Flags {
/** A definition that's initialized before the super call (Scala 2.x only) */
final val Scala2PreSuper = termFlag(58, "<presuper>")
+ /** A macro (Scala 2.x only) */
+ final val Macro = commonFlag(59, "<macro>")
+
/** A method that is known to have inherited default parameters */
- final val InheritedDefaultParams = termFlag(59, "<inherited-default-param>")
+ final val InheritedDefaultParams = termFlag(60, "<inherited-default-param>")
- /** A method that is known to no default parameters */
- final val NoDefaultParams = termFlag(60, "<no-default-param>")
+ /** A method that is known to have no default parameters */
+ final val NoDefaultParams = termFlag(61, "<no-default-param>")
/** A denotation that is valid in all run-ids */
- final val Permanent = commonFlag(61, "<permanent>")
+ final val Permanent = commonFlag(62, "<permanent>")
// --------- Combined Flag Sets and Conjunctions ----------------------
@@ -405,7 +416,10 @@ object Flags {
/** Flags representing modifiers that can appear in trees */
final val ModifierFlags =
- SourceModifierFlags | Trait | Module | Param | Synthetic | Package
+ SourceModifierFlags | Module | Param | Synthetic | Package | Local
+ // | Trait is subsumed by commonFlags(Lazy) from SourceModifierFlags
+
+ assert(ModifierFlags.isTermFlags && ModifierFlags.isTypeFlags)
/** Flags representing access rights */
final val AccessFlags = Private | Protected | Local
@@ -438,8 +452,8 @@ object Flags {
/** The flags of the self symbol */
final val SelfSymFlags = Private | Local | Deferred
- /** The flags of a type parameter */
- final val TypeParamCreationFlags = TypeParam | Deferred | Protected | Local
+ /** The flags of a class type parameter */
+ final def ClassTypeParamCreationFlags = TypeParam | Deferred | Protected | Local
/** Flags that can apply to both a module val and a module class, except those that
* are added at creation anyway
diff --git a/src/dotty/tools/dotc/core/NameOps.scala b/src/dotty/tools/dotc/core/NameOps.scala
index 5bdafcf8a..404a0844a 100644
--- a/src/dotty/tools/dotc/core/NameOps.scala
+++ b/src/dotty/tools/dotc/core/NameOps.scala
@@ -47,6 +47,13 @@ object NameOps {
}
}
+ object SuperAccessorName {
+ val pre = nme.SUPER_PREFIX
+ def apply(name: TermName): TermName = pre ++ name
+ def unapply(name: TermName): Option[TermName] =
+ if (name startsWith pre) Some(name.drop(pre.length).asTermName) else None
+ }
+
implicit class NameDecorator[N <: Name](val name: N) extends AnyVal {
import nme._
@@ -59,7 +66,6 @@ object NameOps {
def isLocalDummyName = name startsWith LOCALDUMMY_PREFIX
def isLoopHeaderLabel = (name startsWith WHILE_PREFIX) || (name startsWith DO_WHILE_PREFIX)
def isProtectedAccessorName = name startsWith PROTECTED_PREFIX
- def isSuperAccessorName = name startsWith SUPER_PREFIX
def isReplWrapperName = name containsSlice INTERPRETER_IMPORT_WRAPPER
def isSetterName = name endsWith SETTER_SUFFIX
def isTraitSetterName = isSetterName && (name containsSlice TRAIT_SETTER_SEPARATOR)
@@ -126,6 +132,9 @@ object NameOps {
if (flags is (ModuleClass, butNot = Package)) name.asTypeName.moduleClassName.asInstanceOf[N]
else name
+ /** The superaccessor for method with given name */
+ def superName: TermName = (nme.SUPER_PREFIX ++ name).toTermName
+
/** The expanded name of `name` relative to this class `base` with given `separator`
*/
def expandedName(base: Symbol, separator: Name = nme.EXPAND_SEPARATOR)(implicit ctx: Context): N = {
@@ -247,17 +256,13 @@ object NameOps {
else -1
}
- /** The name of a super-accessor */
- def superAccessorName: TermName =
- SUPER_PREFIX ++ name
-
/** The name of an accessor for protected symbols. */
def protectedAccessorName: TermName =
- PROTECTED_PREFIX ++ name
+ PROTECTED_PREFIX ++ name.unexpandedName()
/** The name of a setter for protected symbols. Used for inherited Java fields. */
- def protectedSetterName(name: Name): TermName =
- PROTECTED_SET_PREFIX ++ name
+ def protectedSetterName: TermName =
+ PROTECTED_SET_PREFIX ++ name.unexpandedName()
def moduleVarName: TermName =
name ++ MODULE_VAR_SUFFIX
diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala
index 4ab04fad0..e0d9e3b5d 100644
--- a/src/dotty/tools/dotc/core/Periods.scala
+++ b/src/dotty/tools/dotc/core/Periods.scala
@@ -67,6 +67,8 @@ object Periods {
/** The first phase of this period */
def firstPhaseId = lastPhaseId - (code & PhaseMask)
+ def containsPhaseId(id: PhaseId) = firstPhaseId <= id && id <= lastPhaseId
+
/** Does this period contain given period? */
def contains(that: Period): Boolean = {
// Let this = (r1, l1, d1), that = (r2, l2, d2)
@@ -106,6 +108,11 @@ object Periods {
else
Nowhere
+ def | (that: Period): Period =
+ Period(this.runId,
+ this.firstPhaseId min that.firstPhaseId,
+ this.lastPhaseId max that.lastPhaseId)
+
override def toString = s"Period($firstPhaseId..$lastPhaseId, run = $runId)"
}
diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala
index 7bc5f3052..aabde4cf9 100644
--- a/src/dotty/tools/dotc/core/Phases.scala
+++ b/src/dotty/tools/dotc/core/Phases.scala
@@ -9,7 +9,6 @@ import Denotations._
import config.Printers._
import scala.collection.mutable.{ListBuffer, ArrayBuffer}
import dotty.tools.dotc.transform.TreeTransforms.{TreeTransformer, TreeTransform}
-import dotty.tools.dotc.transform.PostTyperTransformers.PostTyperTransformer
import dotty.tools.dotc.transform.TreeTransforms
import TreeTransforms.Separator
import Periods._
@@ -72,12 +71,10 @@ object Phases {
/** Squash TreeTransform's beloning to same sublist to a single TreeTransformer
* Each TreeTransform gets own period,
* whereas a combined TreeTransformer gets period equal to union of periods of it's TreeTransforms
- * first TreeTransformer emitted is PostTyperTransformer that simplifies trees, see it's documentation
*/
private def squashPhases(phasess: List[List[Phase]]): Array[Phase] = {
val squashedPhases = ListBuffer[Phase]()
var prevPhases: Set[String] = Set.empty
- var postTyperEmmited = false
var i = 0
while (i < phasess.length) {
if (phasess(i).length > 1) {
@@ -95,17 +92,10 @@ object Phases {
}
}
val transforms = phasess(i).asInstanceOf[List[TreeTransform]]
- val block =
- if (!postTyperEmmited) {
- postTyperEmmited = true
- new PostTyperTransformer {
- override def name: String = transformations.map(_.name).mkString("TreeTransform:{", ", ", "}")
- override def transformations: Array[TreeTransform] = transforms.toArray
- }
- } else new TreeTransformer {
- override def name: String = transformations.map(_.name).mkString("TreeTransform:{", ", ", "}")
- override def transformations: Array[TreeTransform] = transforms.toArray
- }
+ val block = new TreeTransformer {
+ override def name: String = transformations.map(_.name).mkString("TreeTransform:{", ", ", "}")
+ override def transformations: Array[TreeTransform] = transforms.toArray
+ }
squashedPhases += block
prevPhases ++= phasess(i).map(_.name)
block.init(this, phasess(i).head.id, phasess(i).last.id)
diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala
index 367713d11..919e35a7e 100644
--- a/src/dotty/tools/dotc/core/Scopes.scala
+++ b/src/dotty/tools/dotc/core/Scopes.scala
@@ -18,6 +18,7 @@ import SymDenotations._
import printing.Texts._
import printing.Printer
import util.common._
+import util.DotClass
import SymDenotations.NoDenotation
import collection.mutable.ListBuffer
@@ -55,7 +56,7 @@ object Scopes {
* or to delete them. These methods are provided by subclass
* MutableScope.
*/
- abstract class Scope extends printing.Showable with Iterable[Symbol] {
+ abstract class Scope extends DotClass with printing.Showable with Iterable[Symbol] {
/** The last scope-entry from which all others are reachable via `prev` */
private[dotc] def lastEntry: ScopeEntry
@@ -77,8 +78,8 @@ object Scopes {
*/
def iterator: Iterator[Symbol] = toList.iterator
- /** Returns a new scope with the same content as this one. */
- def cloneScope(implicit ctx: Context): Scope
+ /** Returns a new mutable scope with the same content as this one. */
+ def cloneScope(implicit ctx: Context): MutableScope
/** Is the scope empty? */
override def isEmpty: Boolean = lastEntry eq null
@@ -354,7 +355,7 @@ object Scopes {
override def size = 0
override def nestingLevel = 0
override def toList = Nil
- override def cloneScope(implicit ctx: Context): Scope = this
+ override def cloneScope(implicit ctx: Context): MutableScope = unsupported("cloneScope")
override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = null
override def lookupNextEntry(entry: ScopeEntry)(implicit ctx: Context): ScopeEntry = null
}
diff --git a/src/dotty/tools/dotc/core/Signature.scala b/src/dotty/tools/dotc/core/Signature.scala
index eb85fbb99..22d038d11 100644
--- a/src/dotty/tools/dotc/core/Signature.scala
+++ b/src/dotty/tools/dotc/core/Signature.scala
@@ -49,7 +49,7 @@ object Signature {
* a type different from PolyType, MethodType, or ExprType.
*/
val NotAMethod = Signature(List(), EmptyTypeName)
-
+
/** The signature of an overloaded denotation.
*/
val OverloadedSignature = Signature(List(tpnme.OVERLOADED), EmptyTypeName)
diff --git a/src/dotty/tools/dotc/core/Substituters.scala b/src/dotty/tools/dotc/core/Substituters.scala
index 1b96de47e..3d14317cb 100644
--- a/src/dotty/tools/dotc/core/Substituters.scala
+++ b/src/dotty/tools/dotc/core/Substituters.scala
@@ -205,7 +205,11 @@ trait Substituters { this: Context =>
final class SubstMap(from: List[Symbol], to: List[Type]) extends DeepTypeMap {
def apply(tp: Type): Type = subst(tp, from, to, this)
}
-
+/* not needed yet
+ final class SubstDealiasMap(from: List[Symbol], to: List[Type]) extends SubstMap(from, to) {
+ override def apply(tp: Type): Type = subst(tp.dealias, from, to, this)
+ }
+*/
final class SubstSymMap(from: List[Symbol], to: List[Symbol]) extends DeepTypeMap {
def apply(tp: Type): Type = substSym(tp, from, to, this)
}
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 802762045..b0a09baf0 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -83,6 +83,9 @@ object SymDenotations {
/** The owner of the symbol; overridden in NoDenotation */
def owner: Symbol = ownerIfExists
+ /** Same as owner, except returns NoSymbol for NoSymbol */
+ def maybeOwner: Symbol = if (exists) owner else NoSymbol
+
/** The flag set */
final def flags(implicit ctx: Context): FlagSet = { ensureCompleted(); myFlags }
@@ -212,6 +215,14 @@ object SymDenotations {
final def addAnnotation(annot: Annotation): Unit =
annotations = annot :: myAnnotations
+ /** Remove annotation with given class from this denotation */
+ final def removeAnnotation(cls: Symbol)(implicit ctx: Context): Unit =
+ annotations = myAnnotations.filterNot(_ matches cls)
+
+ /** Copy all annotations from given symbol by adding them to this symbol */
+ final def addAnnotations(from: Symbol)(implicit ctx: Context): Unit =
+ from.annotations.foreach(addAnnotation)
+
@tailrec
private def dropOtherAnnotations(anns: List[Annotation], cls: Symbol)(implicit ctx: Context): List[Annotation] = anns match {
case ann :: rest => if (ann matches cls) anns else dropOtherAnnotations(rest, cls)
@@ -321,6 +332,12 @@ object SymDenotations {
final def isAnonymousClass(implicit ctx: Context): Boolean =
initial.asSymDenotation.name startsWith tpnme.ANON_CLASS
+ /** Is symbol a primitive value class? */
+ def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains symbol
+
+ /** Is symbol a phantom class for which no runtime representation exists? */
+ def isPhantomClass(implicit ctx: Context) = defn.PhantomClasses contains symbol
+
/** Is this symbol a class representing a refinement? These classes
* are used only temporarily in Typer and Unpickler as an intermediate
* step for creating Refinement types.
@@ -447,7 +464,7 @@ object SymDenotations {
def accessWithin(boundary: Symbol) =
ctx.owner.isContainedIn(boundary) &&
(!(this is JavaDefined) || // disregard package nesting for Java
- ctx.owner.enclosingPackage == boundary.enclosingPackage)
+ ctx.owner.enclosingPackageClass == boundary.enclosingPackageClass)
/** Are we within definition of linked class of `boundary`? */
def accessWithinLinked(boundary: Symbol) = {
@@ -572,6 +589,12 @@ object SymDenotations {
NoSymbol
}
+ /** The field accessed by this getter or setter */
+ def accessedField(implicit ctx: Context): Symbol = {
+ val fieldName = if (isSetter) name.asTermName.setterToGetter else name
+ owner.info.decl(fieldName).suchThat(d => !(d is Method)).symbol
+ }
+
/** The chain of owners of this denotation, starting with the denoting symbol itself */
final def ownersIterator(implicit ctx: Context) = new Iterator[Symbol] {
private[this] var current = symbol
@@ -624,8 +647,8 @@ object SymDenotations {
}
/** The package class containing this denotation */
- final def enclosingPackage(implicit ctx: Context): Symbol =
- if (this is PackageClass) symbol else owner.enclosingPackage
+ final def enclosingPackageClass(implicit ctx: Context): Symbol =
+ if (this is PackageClass) symbol else owner.enclosingPackageClass
/** The module object with the same (term-) name as this class or module class,
* and which is also defined in the same scope and compilation unit.
@@ -747,7 +770,6 @@ object SymDenotations {
loop(base.info.baseClasses.dropWhile(owner != _).tail)
}
-
/** A a member of class `base` is incomplete if
* (1) it is declared deferred or
* (2) it is abstract override and its super symbol in `base` is
@@ -809,6 +831,11 @@ object SymDenotations {
else if (this is Contravariant) -1
else 0
+ /** The flags to be used for a type parameter owned by this symbol.
+ * Overridden by ClassDenotation.
+ */
+ def typeParamCreationFlags: FlagSet = TypeParam
+
override def toString = {
val kindString =
if (myFlags is ModuleClass) "module class"
@@ -848,6 +875,22 @@ object SymDenotations {
/** Install this denotation as the result of the given denotation transformer. */
override def installAfter(phase: DenotTransformer)(implicit ctx: Context): Unit =
super.installAfter(phase)
+
+ /** Remove private modifier from symbol's definition. If this symbol
+ * is not a constructor nor a static module, rename it by expanding its name to avoid name clashes
+ * @param base the fully qualified name of this class will be appended if name expansion is needed
+ */
+ final def makeNotPrivateAfter(base: Symbol, phase: DenotTransformer)(implicit ctx: Context): Unit = {
+ if (this.is(Private)) {
+ val newName =
+ if (this.is(Module) && isStatic || isClassConstructor) name
+ else {
+ if (this.is(Module)) moduleClass.makeNotPrivateAfter(base, phase)
+ name.expandedName(base)
+ }
+ copySymDenotation(name = newName, initFlags = flags &~ Private).installAfter(phase)
+ }
+ }
}
/** The contents of a class definition during a period
@@ -895,6 +938,15 @@ object SymDenotations {
case _ => Nil
}
+ /** The symbol of the superclass, NoSymbol if no superclass exists */
+ def superClass(implicit ctx: Context): Symbol = classParents match {
+ case parent :: _ =>
+ val cls = parent.classSymbol
+ if (cls is Trait) NoSymbol else cls
+ case _ =>
+ NoSymbol
+ }
+
/** The denotation is fully completed: all attributes are fully defined.
* ClassDenotations compiled from source are first completed, then fully completed.
* @see Namer#ClassCompleter
@@ -938,6 +990,7 @@ object SymDenotations {
mySuperClassBits = null
myMemberFingerPrint = FingerPrint.unknown
myMemberCache = null
+ myMemberCachePeriod = Nowhere
memberNamesCache = SimpleMap.Empty
}
@@ -1036,6 +1089,8 @@ object SymDenotations {
(symbol eq defn.NothingClass) ||
(symbol eq defn.NullClass) && (base ne defn.NothingClass))
+ final override def typeParamCreationFlags = ClassTypeParamCreationFlags
+
private[this] var myMemberFingerPrint: FingerPrint = FingerPrint.unknown
private def computeMemberFingerPrint(implicit ctx: Context): FingerPrint = {
@@ -1070,9 +1125,13 @@ object SymDenotations {
}
private[this] var myMemberCache: LRUCache[Name, PreDenotation] = null
+ private[this] var myMemberCachePeriod: Period = Nowhere
- private def memberCache: LRUCache[Name, PreDenotation] = {
- if (myMemberCache == null) myMemberCache = new LRUCache
+ private def memberCache(implicit ctx: Context): LRUCache[Name, PreDenotation] = {
+ if (myMemberCachePeriod != ctx.period) {
+ myMemberCache = new LRUCache
+ myMemberCachePeriod = ctx.period
+ }
myMemberCache
}
@@ -1289,9 +1348,20 @@ object SymDenotations {
decls.denotsNamed(cname).first.symbol
}
- def underlyingOfValueClass: Type = ???
-
- def valueClassUnbox: Symbol = ???
+ /** If this class has the same `decls` scope reference in `phase` and
+ * `phase.next`, install a new denotation with a cloned scope in `phase.next`.
+ * @pre Can only be called in `phase.next`.
+ */
+ def ensureFreshScopeAfter(phase: DenotTransformer)(implicit ctx: Context): Unit = {
+ assert(ctx.phaseId == phase.next.id)
+ val prevCtx = ctx.withPhase(phase)
+ val ClassInfo(pre, _, ps, decls, selfInfo) = classInfo
+ if (classInfo(prevCtx).decls eq decls) {
+ copySymDenotation(
+ info = ClassInfo(pre, classSymbol, ps, decls.cloneScope, selfInfo),
+ initFlags = this.flags &~ Frozen).installAfter(phase)
+ }
+ }
}
/** The denotation of a package class.
diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala
index bebad60cc..886c728b7 100644
--- a/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -12,7 +12,7 @@ import scala.compat.Platform.currentTime
import dotty.tools.io.{ ClassPath, AbstractFile }
import Contexts._, Symbols._, Flags._, SymDenotations._, Types._, Scopes._, util.Positions._, Names._
import StdNames._, NameOps._
-import Decorators.StringDecorator
+import Decorators.{StringDecorator, StringInterpolators}
import pickling.ClassfileParser
object SymbolLoaders {
@@ -69,8 +69,8 @@ class SymbolLoaders {
// require yjp.jar at runtime. See SI-2089.
if (ctx.settings.termConflict.isDefault)
throw new TypeError(
- s"""$owner contains object and package with same name: $pname
- |one of them needs to be removed from classpath""".stripMargin)
+ sm"""$owner contains object and package with same name: $pname
+ |one of them needs to be removed from classpath""")
else if (ctx.settings.termConflict.value == "package") {
ctx.warning(
s"Resolving package/object name conflict in favor of package ${preExisting.fullName}. The object will be inaccessible.")
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 26553ddff..1767d7c0c 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -16,6 +16,7 @@ import printing.Printer
import Types._
import Annotations._
import util.Positions._
+import DenotTransformers._
import StdNames._
import NameOps._
import ast.tpd.{TreeTypeMap, Tree}
@@ -250,7 +251,7 @@ trait Symbols { this: Context =>
val tparams = tparamBuf.toList
val bounds = boundsFn(trefBuf.toList)
for ((name, tparam, bound) <- (names, tparams, bounds).zipped)
- tparam.denot = SymDenotation(tparam, owner, name, flags | TypeParamCreationFlags, bound)
+ tparam.denot = SymDenotation(tparam, owner, name, flags | owner.typeParamCreationFlags, bound)
tparams
}
@@ -260,16 +261,14 @@ trait Symbols { this: Context =>
newSymbol(owner, name, SyntheticArtifact,
if (name.isTypeName) TypeAlias(ErrorType) else ErrorType)
- type OwnerMap = Symbol => Symbol
-
/** Map given symbols, subjecting all types to given type map and owner map.
* Cross symbol references are brought over from originals to copies.
* Do not copy any symbols if all attributes of all symbols stay the same.
*/
def mapSymbols(
originals: List[Symbol],
- typeMap: TypeMap = IdentityTypeMap,
- ownerMap: OwnerMap = identity)
+ typeMap: Type => Type = IdentityTypeMap,
+ ownerMap: Symbol => Symbol = identity)
=
if (originals forall (sym =>
(typeMap(sym.info) eq sym.info) && (ownerMap(sym.owner) eq sym.owner)))
@@ -358,6 +357,10 @@ object Symbols {
final def asType(implicit ctx: Context): TypeSymbol = { assert(isType, s"isType called on not-a-Type $this"); asInstanceOf[TypeSymbol] }
final def asClass: ClassSymbol = asInstanceOf[ClassSymbol]
+ /** Special cased here, because it may be used on naked symbols in substituters */
+ final def isStatic(implicit ctx: Context): Boolean =
+ lastDenot != null && denot.isStatic
+
/** A unique, densely packed integer tag for each class symbol, -1
* for all other symbols. To save memory, this method
* should be called only if class is a super class of some other class.
@@ -372,6 +375,17 @@ object Symbols {
this
}
+ /** Enter this symbol in its class owner after given `phase`. Create a fresh
+ * denotation for its owner class if the class has not yet already one
+ * that starts being valid after `phase`.
+ * @pre Symbol is a class member
+ */
+ def enteredAfter(phase: DenotTransformer)(implicit ctx: Context): this.type = {
+ val nextCtx = ctx.withPhase(phase.next)
+ this.owner.asClass.ensureFreshScopeAfter(phase)(nextCtx)
+ entered(nextCtx)
+ }
+
/** This symbol, if it exists, otherwise the result of evaluating `that` */
def orElse(that: => Symbol)(implicit ctx: Context) =
if (this.exists) this else that
@@ -381,14 +395,8 @@ object Symbols {
/** Is this symbol a user-defined value class? */
final def isDerivedValueClass(implicit ctx: Context): Boolean =
- false && // value classes are not supported yet
- isClass && denot.derivesFrom(defn.AnyValClass) && !isPrimitiveValueClass
-
- /** Is symbol a primitive value class? */
- def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains this
-
- /** Is symbol a phantom class for which no runtime representation exists? */
- def isPhantomClass(implicit ctx: Context) = defn.PhantomClasses contains this
+ false // will migrate to ValueClasses.isDerivedValueClass;
+ // unsupported value class code will continue to use this stub while it exists
/** The current name of this symbol */
final def name(implicit ctx: Context): ThisName = denot.name.asInstanceOf[ThisName]
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 4885b30d8..289515ae1 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -813,11 +813,15 @@ object Types {
if (from1.isEmpty) ctx.subst1(this, from.head, to.head, null)
else {
val from2 = from1.tail
- if (from2.isEmpty) ctx.subst2(this, from.head, to.head, from.tail.head, to.tail.head, null)
+ if (from2.isEmpty) ctx.subst2(this, from.head, to.head, from1.head, to.tail.head, null)
else ctx.subst(this, from, to, null)
}
}
+/* Not needed yet:
+ final def substDealias(from: List[Symbol], to: List[Type])(implicit ctx: Context): Type =
+ new ctx.SubstDealiasMap(from, to).apply(this)
+*/
/** Substitute all types of the form `PolyParam(from, N)` by
* `PolyParam(to, N)`.
*/
@@ -1602,17 +1606,22 @@ object Types {
// and therefore two different poly types would never be equal.
/** A trait that mixes in functionality for signature caching */
- trait SignedType extends Type {
+ trait MethodicType extends Type {
private[this] var mySignature: Signature = _
private[this] var mySignatureRunId: Int = NoRunId
protected def computeSignature(implicit ctx: Context): Signature
- protected def resultSignature(implicit ctx: Context) = resultType match {
- case rtp: SignedType => rtp.signature
+ protected def resultSignature(implicit ctx: Context) = try resultType match {
+ case rtp: MethodicType => rtp.signature
case tp => Signature(tp, isJava = false)
}
+ catch {
+ case ex: AssertionError =>
+ println(i"failure while taking result signture of $resultType")
+ throw ex
+ }
final override def signature(implicit ctx: Context): Signature = {
if (ctx.runId != mySignatureRunId) {
@@ -1623,7 +1632,7 @@ object Types {
}
}
- trait MethodOrPoly extends SignedType
+ trait MethodOrPoly extends MethodicType
abstract case class MethodType(paramNames: List[TermName], paramTypes: List[Type])
(resultTypeExp: MethodType => Type)
@@ -1717,6 +1726,8 @@ object Types {
def apply(paramNames: List[TermName], paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType
def apply(paramNames: List[TermName], paramTypes: List[Type], resultType: Type)(implicit ctx: Context): MethodType =
apply(paramNames, paramTypes)(_ => resultType)
+ def apply(paramTypes: List[Type])(resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
+ apply(nme.syntheticParamNames(paramTypes.length), paramTypes)(resultTypeExp)
def apply(paramTypes: List[Type], resultType: Type)(implicit ctx: Context): MethodType =
apply(nme.syntheticParamNames(paramTypes.length), paramTypes, resultType)
def fromSymbols(params: List[Symbol], resultType: Type)(implicit ctx: Context) = {
@@ -1748,7 +1759,7 @@ object Types {
}
abstract case class ExprType(override val resultType: Type)
- extends CachedProxyType with TermType with SignedType {
+ extends CachedProxyType with TermType with MethodicType {
override def underlying(implicit ctx: Context): Type = resultType
protected def computeSignature(implicit ctx: Context): Signature = resultSignature
def derivedExprType(resultType: Type)(implicit ctx: Context) =
@@ -2019,19 +2030,31 @@ object Types {
decls: Scope,
selfInfo: DotClass /* should be: Type | Symbol */) extends CachedGroundType with TypeType {
- def selfType(implicit ctx: Context): Type = selfInfo match {
- case NoType =>
- if (selfTypeCache == null) selfTypeCache = computeSelfType(cls.typeRef, cls.typeParams)
- selfTypeCache
- case tp: Type => tp
- case self: Symbol => self.info
+ /** The self type of a class is the conjunction of
+ * - the explicit self type if given (or the info of a given self symbol), and
+ * - the fully applied reference to the class itself.
+ */
+ def selfType(implicit ctx: Context): Type = {
+ if (selfTypeCache == null) {
+ def fullRef = fullyAppliedRef(cls.typeRef, cls.typeParams)
+ selfTypeCache = selfInfo match {
+ case NoType =>
+ fullRef
+ case tp: Type =>
+ if (cls is Module) tp else AndType(tp, fullRef)
+ case self: Symbol =>
+ assert(!(cls is Module))
+ AndType(self.info, fullRef)
+ }
+ }
+ selfTypeCache
}
private var selfTypeCache: Type = null
- private def computeSelfType(base: Type, tparams: List[TypeSymbol])(implicit ctx: Context): Type = tparams match {
+ private def fullyAppliedRef(base: Type, tparams: List[TypeSymbol])(implicit ctx: Context): Type = tparams match {
case tparam :: tparams1 =>
- computeSelfType(
+ fullyAppliedRef(
RefinedType(base, tparam.name, TypeRef(cls.thisType, tparam).toBounds(tparam)),
tparams1)
case nil =>
@@ -2077,8 +2100,8 @@ object Types {
if (prefix eq this.prefix) this
else ClassInfo(prefix, cls, classParents, decls, selfInfo)
- def derivedClassInfo(prefix: Type = this.prefix, classParents: List[TypeRef] = classParents, selfInfo: DotClass = this.selfInfo)(implicit ctx: Context) =
- if ((prefix eq this.prefix) && (classParents eq this.classParents) && (selfInfo eq this.selfInfo)) this
+ def derivedClassInfo(prefix: Type = this.prefix, classParents: List[TypeRef] = classParents, decls: Scope = this.decls, selfInfo: DotClass = this.selfInfo)(implicit ctx: Context) =
+ if ((prefix eq this.prefix) && (classParents eq this.classParents) && (decls eq this.decls) && (selfInfo eq this.selfInfo)) this
else ClassInfo(prefix, cls, classParents, decls, selfInfo)
override def computeHash = doHash(cls, prefix)
@@ -2431,7 +2454,7 @@ object Types {
case self: Type => this(self)
case _ => tp.self
}
- tp.derivedClassInfo(prefix1, parents1, self1)
+ tp.derivedClassInfo(prefix1, parents1, tp.decls, self1)
}
}
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 0ed301732..59658c9c1 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -48,8 +48,8 @@ class ClassfileParser(
case e: RuntimeException =>
if (ctx.debug) e.printStackTrace()
throw new IOException(
- s"""class file $classfile is broken, reading aborted with $e.getClass
- |${Option(e.getMessage).getOrElse("")}""".stripMargin)
+ sm"""class file $classfile is broken, reading aborted with $e.getClass
+ |${Option(e.getMessage).getOrElse("")}""")
}
private def parseHeader(): Unit = {
@@ -353,7 +353,7 @@ class ClassfileParser(
val tpname = subName(':'.==).toTypeName
val expname = if (owner.isClass) tpname.expandedName(owner) else tpname
val s = ctx.newSymbol(
- owner, expname, Flags.TypeParamCreationFlags,
+ owner, expname, owner.typeParamCreationFlags,
typeParamCompleter(index), coord = indexCoord(index))
if (owner.isClass) owner.asClass.enter(s, owner.decls)
tparams = tparams + (tpname -> s)
@@ -702,12 +702,12 @@ class ClassfileParser(
getMember(owner, innerName.toTypeName)
}
assert(result ne NoSymbol,
- s"""failure to resolve inner class:
- |externalName = $externalName,
- |outerName = $outerName,
- |innerName = $innerName
- |owner.fullName = owner.showFullName
- |while parsing ${classfile}""".stripMargin)
+ sm"""failure to resolve inner class:
+ |externalName = $externalName,
+ |outerName = $outerName,
+ |innerName = $innerName
+ |owner.fullName = owner.showFullName
+ |while parsing ${classfile}""")
result
case None =>
@@ -752,7 +752,7 @@ class ClassfileParser(
private def setPrivateWithin(denot: SymDenotation, jflags: Int)(implicit ctx: Context): Unit = {
if ((jflags & (JAVA_ACC_PRIVATE | JAVA_ACC_PUBLIC)) == 0)
- denot.privateWithin = denot.enclosingPackage
+ denot.privateWithin = denot.enclosingPackageClass
}
private def isPrivate(flags: Int) = (flags & JAVA_ACC_PRIVATE) != 0
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index dd26b20df..36b2c99bf 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -53,10 +53,10 @@ object UnPickler {
val result = restpe.parameterizeWith(tparams)
for ((msg, pos) <- err)
ctx.warning(
- s"""$msg
- |originally parsed type : ${tp.show}
- |will be approximated by: ${result.show}.
- |Proceed at own risk.""".stripMargin)
+ sm"""$msg
+ |originally parsed type : ${tp.show}
+ |will be approximated by: ${result.show}.
+ |Proceed at own risk.""")
result
}
else
@@ -161,8 +161,8 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
protected def errorBadSignature(msg: String, original: Option[RuntimeException] = None)(implicit ctx: Context) = {
val ex = new BadSignature(
- s"""error reading Scala signature of $classRoot from $source:
- |error occured at position $readIndex: $msg""".stripMargin)
+ sm"""error reading Scala signature of $classRoot from $source:
+ |error occured at position $readIndex: $msg""")
/*if (debug)*/ original.getOrElse(ex).printStackTrace() // !!! DEBUG
throw ex
}
@@ -453,7 +453,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
var flags1 = flags
if (flags is TypeParam) {
name1 = name1.expandedName(owner)
- flags1 |= TypeParamCreationFlags | ExpandedName
+ flags1 |= owner.typeParamCreationFlags | ExpandedName
}
ctx.newSymbol(owner, name1, flags1, localMemberUnpickler, coord = start)
case CLASSsym =>
@@ -1080,7 +1080,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
setSym()
val qualifier = readTreeRef()
val selector = readNameRef()
- Select(qualifier, symbol.namedType)
+ qualifier.select(symbol.namedType)
case IDENTtree =>
setSymName()
Ident(symbol.namedType)
diff --git a/src/dotty/tools/dotc/core/transform/Erasure.scala b/src/dotty/tools/dotc/core/transform/Erasure.scala
index da14f72d1..e35cdd128 100644
--- a/src/dotty/tools/dotc/core/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/core/transform/Erasure.scala
@@ -146,7 +146,7 @@ class Erasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wildcard
if ((cls eq defn.ObjectClass) || cls.isPrimitiveValueClass) Nil
else if (cls eq defn.ArrayClass) defn.ObjectClass.typeRef :: Nil
else removeLaterObjects(classParents.mapConserve(eraseTypeRef))
- tp.derivedClassInfo(this(pre), parents, this(tp.selfType))
+ tp.derivedClassInfo(this(pre), parents, decls, this(tp.selfType))
case NoType | NoPrefix | ErrorType =>
tp
case tp: WildcardType if wildcardOK =>