aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/TypeErasure.scala4
-rw-r--r--src/dotty/tools/dotc/ast/TreeTypeMap.scala2
-rw-r--r--src/dotty/tools/dotc/config/CompilerCommand.scala10
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala15
-rw-r--r--src/dotty/tools/dotc/core/Decorators.scala19
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala2
-rw-r--r--src/dotty/tools/dotc/core/Flags.scala5
-rw-r--r--src/dotty/tools/dotc/core/Scopes.scala10
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala39
-rw-r--r--src/dotty/tools/dotc/core/SymbolLoaders.scala6
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala27
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala2
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala22
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala21
-rw-r--r--src/dotty/tools/dotc/core/Types.scala7
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala41
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala8
-rw-r--r--src/dotty/tools/dotc/reporting/Reporter.scala12
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala2
-rw-r--r--src/dotty/tools/dotc/transform/LambdaLift.scala2
-rw-r--r--src/dotty/tools/dotc/transform/Mixin.scala4
-rw-r--r--src/dotty/tools/dotc/transform/OverridingPairs.scala2
-rw-r--r--src/dotty/tools/dotc/transform/ResolveSuper.scala4
-rw-r--r--src/dotty/tools/dotc/transform/SuperAccessors.scala2
-rw-r--r--src/dotty/tools/dotc/transform/SymUtils.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala8
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala17
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala32
-rw-r--r--test/dotc/tests.scala1
-rw-r--r--test/test/DottyTest.scala5
-rw-r--r--tests/pending/pos/annot.scala5
-rw-r--r--tests/pos/annot-bootstrap.scala8
-rw-r--r--tests/pos/annot.scala6
-rw-r--r--tests/pos/i0268.scala15
34 files changed, 214 insertions, 153 deletions
diff --git a/src/dotty/tools/dotc/TypeErasure.scala b/src/dotty/tools/dotc/TypeErasure.scala
index 973e50e8e..a9ae34213 100644
--- a/src/dotty/tools/dotc/TypeErasure.scala
+++ b/src/dotty/tools/dotc/TypeErasure.scala
@@ -108,7 +108,9 @@ object TypeErasure {
def erasedRef(tp: Type)(implicit ctx: Context): Type = tp match {
case tp: TermRef =>
assert(tp.symbol.exists, tp)
- TermRef(erasedRef(tp.prefix), tp.symbol.asTerm)
+ val tp1 = ctx.makePackageObjPrefixExplicit(tp)
+ if (tp1 ne tp) erasedRef(tp1)
+ else TermRef(erasedRef(tp.prefix), tp.symbol.asTerm)
case tp: ThisType =>
tp
case tp =>
diff --git a/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/src/dotty/tools/dotc/ast/TreeTypeMap.scala
index 846c661f5..98027cd39 100644
--- a/src/dotty/tools/dotc/ast/TreeTypeMap.scala
+++ b/src/dotty/tools/dotc/ast/TreeTypeMap.scala
@@ -170,7 +170,7 @@ final class TreeTypeMap(
val symsChanged = syms ne mapped
val substMap = withSubstitution(syms, mapped)
val fullMap = (substMap /: mapped.filter(_.isClass)) { (tmap, cls) =>
- val origDcls = cls.decls.toList
+ val origDcls = cls.info.decls.toList
val mappedDcls = ctx.mapSymbols(origDcls, tmap)
val tmap1 = tmap.withMappedSyms(origDcls, mappedDcls)
if (symsChanged) (origDcls, mappedDcls).zipped.foreach(cls.asClass.replace)
diff --git a/src/dotty/tools/dotc/config/CompilerCommand.scala b/src/dotty/tools/dotc/config/CompilerCommand.scala
index ec8b17b0d..aa8e7abbf 100644
--- a/src/dotty/tools/dotc/config/CompilerCommand.scala
+++ b/src/dotty/tools/dotc/config/CompilerCommand.scala
@@ -19,11 +19,13 @@ object CompilerCommand extends DotClass {
|Where multiple values are accepted, they should be comma-separated.
| example: -Xplugin:plugin1,plugin2
|<phases> means one or a comma-separated list of:
- | (partial) phase names, phase ids, phase id ranges, or the string "all".
+ | - (partial) phase names with an optional "+" suffix to include the next phase
+ | - the string "all"
| example: -Xprint:all prints all phases.
- | example: -Xprint:expl,24-26 prints phases explicitouter, closelim, dce, jvm.
- | example: -Xprint:-4 prints only the phases up to typer.
- |
+ | example: -Xprint:front,mixin prints the frontend and mixin phases.
+ | example: -Ylog:erasure+ logs the erasure phase and the phase after the erasure phase.
+ | This is useful because during the tree transform of phase X, we often
+ | already are in phase X+1.
""".stripMargin.trim + "\n"
def shortUsage = s"Usage: $cmdName <options> <source files>"
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 98a71dd98..635390ef5 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -146,6 +146,11 @@ object Contexts {
protected def diagnostics_=(diagnostics: Option[StringBuilder]) = _diagnostics = diagnostics
def diagnostics: Option[StringBuilder] = _diagnostics
+ /** The current bounds in force for type parameters appearing in a GADT */
+ private var _gadt: GADTMap = _
+ protected def gadt_=(gadt: GADTMap) = _gadt = gadt
+ def gadt: GADTMap = _gadt
+
/** A map in which more contextual properties can be stored */
private var _moreProperties: Map[String, Any] = _
protected def moreProperties_=(moreProperties: Map[String, Any]) = _moreProperties = moreProperties
@@ -418,6 +423,8 @@ object Contexts {
def setSetting[T](setting: Setting[T], value: T): this.type =
setSettings(setting.updateIn(sstate, value))
+ def setFreshGADTBounds: this.type = { this.gadt = new GADTMap(gadt.bounds); this }
+
def setDebug = setSetting(base.settings.debug, true)
}
@@ -439,6 +446,7 @@ object Contexts {
moreProperties = Map.empty
typeComparer = new TypeComparer(this)
searchHistory = new SearchHistory(0, Map())
+ gadt = new GADTMap(SimpleMap.Empty)
}
object NoContext extends Context {
@@ -593,6 +601,13 @@ object Contexts {
implicit val ctx: Context = initctx
}
+ class GADTMap(initBounds: SimpleMap[Symbol, TypeBounds]) {
+ private var myBounds = initBounds
+ def setBounds(sym: Symbol, b: TypeBounds): Unit =
+ myBounds = myBounds.updated(sym, b)
+ def bounds = myBounds
+ }
+
/** Initial size of superId table */
private final val InitialSuperIdsSize = 4096
diff --git a/src/dotty/tools/dotc/core/Decorators.scala b/src/dotty/tools/dotc/core/Decorators.scala
index e0d7fae33..882729063 100644
--- a/src/dotty/tools/dotc/core/Decorators.scala
+++ b/src/dotty/tools/dotc/core/Decorators.scala
@@ -128,15 +128,22 @@ object Decorators {
def show(implicit ctx: Context) = text.mkString(ctx.settings.pageWidth.value)
}
- /** Implements a test whether a list of strings representing phases contains
- * a given phase. The test returns true if the given phase starts with
- * one of the names in the list of strings, or if the list of strings
- * contains "all".
+ /** Test whether a list of strings representing phases contains
+ * a given phase. See [[config.CompilerCommand#explainAdvanced]] for the
+ * exact meaning of "contains" here.
*/
implicit class PhaseListDecorator(val names: List[String]) extends AnyVal {
- def containsPhase(phase: Phase): Boolean = phase match {
+ def containsPhase(phase: Phase): Boolean = phase match {
case phase: TreeTransformer => phase.transformations.exists(trans => containsPhase(trans.phase))
- case _ => names exists (n => n == "all" || phase.phaseName.startsWith(n))
+ case _ =>
+ names exists { name =>
+ name == "all" || {
+ val strippedName = name.stripSuffix("+")
+ val logNextPhase = name ne strippedName
+ phase.phaseName.startsWith(strippedName) ||
+ (logNextPhase && phase.prev.phaseName.startsWith(strippedName))
+ }
+ }
}
}
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index a7c7ac3c6..5daeed0f8 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -64,7 +64,7 @@ class Definitions {
private def newAliasType(name: TypeName, tpe: Type, flags: FlagSet = EmptyFlags): TypeSymbol = {
val sym = newSymbol(ScalaPackageClass, name, flags, TypeAlias(tpe))
- ScalaPackageClass.preDecls.enter(sym)
+ ScalaPackageClass.currentPackageDecls.enter(sym)
sym
}
diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala
index 0e86a2936..53beae838 100644
--- a/src/dotty/tools/dotc/core/Flags.scala
+++ b/src/dotty/tools/dotc/core/Flags.scala
@@ -301,9 +301,6 @@ object Flags {
/** Method is assumed to be stable */
final val Stable = termFlag(24, "<stable>")
- /** Info can be refined during GADT pattern match */
- final val GADTFlexType = typeFlag(24, "<gadt-flex-type>")
-
/** A case parameter accessor */
final val CaseAccessor = termFlag(25, "<caseaccessor>")
@@ -553,7 +550,7 @@ object Flags {
/** A Java interface, potentially with default methods */
final val JavaTrait = allOf(JavaDefined, Trait, NoInits)
-
+
/** A Java interface */
final val JavaInterface = allOf(JavaDefined, Trait)
diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala
index cd1eacc91..70bcbdee6 100644
--- a/src/dotty/tools/dotc/core/Scopes.scala
+++ b/src/dotty/tools/dotc/core/Scopes.scala
@@ -93,7 +93,7 @@ object Scopes {
/** Lookup next entry with same name as this one */
def lookupNextEntry(entry: ScopeEntry)(implicit ctx: Context): ScopeEntry
-
+
/** Lookup a symbol */
final def lookup(name: Name)(implicit ctx: Context): Symbol = {
val e = lookupEntry(name)
@@ -138,7 +138,9 @@ object Scopes {
}
def implicitDecls(implicit ctx: Context): List[TermRef] = Nil
-
+
+ def openForMutations: MutableScope = unsupported("openForMutations")
+
final def toText(printer: Printer): Text = printer.toText(this)
}
@@ -374,6 +376,8 @@ object Scopes {
}
syms
}
+
+ override def openForMutations: MutableScope = this
}
/** Create a new scope */
@@ -404,7 +408,7 @@ object Scopes {
/** The empty scope (immutable).
*/
object EmptyScope extends Scope {
- override def lastEntry = null
+ override private[dotc] def lastEntry = null
override def size = 0
override def nestingLevel = 0
override def toList = Nil
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index eccdcbfb9..b4927b5d4 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -45,7 +45,7 @@ trait SymDenotations { this: Context =>
val owner = denot.owner.denot
stillValid(owner) && (
!owner.isClass
- || (owner.decls.lookupAll(denot.name) contains denot.symbol)
+ || (owner.unforcedDecls.lookupAll(denot.name) contains denot.symbol)
|| denot.isSelfSym
)
} catch {
@@ -234,24 +234,31 @@ object SymDenotations {
final def ensureCompleted()(implicit ctx: Context): Unit = info
/** The symbols defined in this class or object.
+ * Careful! This coes not force the type, so is compilation order dependent.
+ * This method should be used only in the following circumstances:
+ *
+ * 1. When accessing type parameters or type parameter accessors (both are entered before
+ * completion).
+ * 2. When obtaining the current scope in order to enter, rename or delete something there.
+ * 3. When playing it safe in order not to raise CylicReferences, e.g. for printing things
+ * or taking more efficient shortcuts (e.g. the stillValid test).
*/
- final def decls(implicit ctx: Context): Scope = myInfo match {
+ final def unforcedDecls(implicit ctx: Context): Scope = myInfo match {
case cinfo: LazyType =>
val knownDecls = cinfo.decls
if (knownDecls ne EmptyScope) knownDecls
- else { completeFrom(cinfo); decls } // complete-once
+ else { completeFrom(cinfo); unforcedDecls } // complete-once
case _ => info.decls
}
/** If this is a package class, the symbols entered in it
* before it is completed. (this is needed to eagerly enter synthetic
* aliases such as AnyRef into a package class without forcing it.
- * Right now, I believe the only usage is for the AnyRef alias
- * in Definitions.
+ * Right now, the only usage is for the AnyRef alias in Definitions.
*/
- final def preDecls(implicit ctx: Context): MutableScope = myInfo match {
- case pinfo: SymbolLoaders # PackageLoader => pinfo.preDecls
- case _ => decls.asInstanceOf[MutableScope]
+ final private[core] def currentPackageDecls(implicit ctx: Context): MutableScope = myInfo match {
+ case pinfo: SymbolLoaders # PackageLoader => pinfo.currentDecls
+ case _ => unforcedDecls.openForMutations
}
// ------ Names ----------------------------------------------
@@ -997,7 +1004,7 @@ object SymDenotations {
def computeTypeParams = {
if (ctx.erasedTypes || is(Module)) Nil // fast return for modules to avoid scanning package decls
else if (this ne initial) initial.asSymDenotation.typeParams
- else decls.filter(sym =>
+ else unforcedDecls.filter(sym =>
(sym is TypeParam) && sym.owner == symbol).asInstanceOf[List[TypeSymbol]]
}
if (myTypeParams == null) myTypeParams = computeTypeParams
@@ -1228,7 +1235,7 @@ object SymDenotations {
def enter(sym: Symbol, scope: Scope = EmptyScope)(implicit ctx: Context): Unit = {
val mscope = scope match {
case scope: MutableScope => scope
- case _ => decls.asInstanceOf[MutableScope]
+ case _ => unforcedDecls.openForMutations
}
if (this is PackageClass) {
val entry = mscope.lookupEntry(sym.name)
@@ -1258,7 +1265,7 @@ object SymDenotations {
*/
def replace(prev: Symbol, replacement: Symbol)(implicit ctx: Context): Unit = {
require(!(this is Frozen))
- decls.asInstanceOf[MutableScope].replace(prev, replacement)
+ unforcedDecls.openForMutations.replace(prev, replacement)
if (myMemberCache != null)
myMemberCache invalidate replacement.name
}
@@ -1269,7 +1276,7 @@ object SymDenotations {
*/
def delete(sym: Symbol)(implicit ctx: Context) = {
require(!(this is Frozen))
- info.decls.asInstanceOf[MutableScope].unlink(sym)
+ info.decls.openForMutations.unlink(sym)
if (myMemberFingerPrint != FingerPrint.unknown)
computeMemberFingerPrint
if (myMemberCache != null)
@@ -1281,7 +1288,7 @@ object SymDenotations {
* have existing symbols.
*/
final def membersNamed(name: Name)(implicit ctx: Context): PreDenotation = {
- val privates = decls.denotsNamed(name, selectPrivate)
+ val privates = info.decls.denotsNamed(name, selectPrivate)
privates union nonPrivateMembersNamed(name).filterDisjoint(privates)
}
@@ -1311,7 +1318,7 @@ object SymDenotations {
(memberFingerPrint contains name)) {
Stats.record("computeNPMembersNamed after fingerprint")
ensureCompleted()
- val ownDenots = decls.denotsNamed(name, selectNonPrivate)
+ val ownDenots = info.decls.denotsNamed(name, selectNonPrivate)
if (debugTrace) // DEBUG
println(s"$this.member($name), ownDenots = $ownDenots")
def collect(denots: PreDenotation, parents: List[TypeRef]): PreDenotation = parents match {
@@ -1458,14 +1465,14 @@ object SymDenotations {
override def primaryConstructor(implicit ctx: Context): Symbol = {
val cname = if (this is ImplClass) nme.IMPLCLASS_CONSTRUCTOR else nme.CONSTRUCTOR
- decls.denotsNamed(cname).last.symbol // denotsNamed returns Symbols in reverse order of occurrence
+ info.decls.denotsNamed(cname).last.symbol // denotsNamed returns Symbols in reverse order of occurrence
}
/** The parameter accessors of this class. Term and type accessors,
* getters and setters are all returned int his list
*/
def paramAccessors(implicit ctx: Context): List[Symbol] =
- decls.filter(_ is ParamAccessor).toList
+ unforcedDecls.filter(_ is ParamAccessor).toList
/** 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`.
diff --git a/src/dotty/tools/dotc/core/SymbolLoaders.scala b/src/dotty/tools/dotc/core/SymbolLoaders.scala
index 76ba3885e..0ad34e16a 100644
--- a/src/dotty/tools/dotc/core/SymbolLoaders.scala
+++ b/src/dotty/tools/dotc/core/SymbolLoaders.scala
@@ -148,13 +148,13 @@ class SymbolLoaders {
override def sourceModule(implicit ctx: Context) = _sourceModule
def description = "package loader " + classpath.name
- private[core] val preDecls: MutableScope = newScope
+ private[core] val currentDecls: MutableScope = newScope
def doComplete(root: SymDenotation)(implicit ctx: Context): Unit = {
assert(root is PackageClass, root)
def maybeModuleClass(classRep: ClassPath#ClassRep) = classRep.name.last == '$'
val pre = root.owner.thisType
- root.info = ClassInfo(pre, root.symbol.asClass, Nil, preDecls, pre select sourceModule)
+ root.info = ClassInfo(pre, root.symbol.asClass, Nil, currentDecls, pre select sourceModule)
if (!sourceModule.isCompleted)
sourceModule.completer.complete(sourceModule)
if (!root.isRoot) {
@@ -162,7 +162,7 @@ class SymbolLoaders {
if (!maybeModuleClass(classRep))
initializeFromClassPath(root.symbol, classRep)
for (classRep <- classpath.classes)
- if (maybeModuleClass(classRep) && !root.decls.lookup(classRep.name.toTypeName).exists)
+ if (maybeModuleClass(classRep) && !root.unforcedDecls.lookup(classRep.name.toTypeName).exists)
initializeFromClassPath(root.symbol, classRep)
}
if (!root.isEmptyPackage)
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 9be75c11a..13b61c0fd 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -192,7 +192,7 @@ trait Symbols { this: Context =>
def stubCompleter = new StubInfo()
val normalizedOwner = if (owner is ModuleVal) owner.moduleClass else owner
println(s"creating stub for ${name.show}, owner = ${normalizedOwner.denot.debugString}, file = $file")
- println(s"decls = ${normalizedOwner.decls.toList.map(_.debugString).mkString("\n ")}") // !!! DEBUG
+ println(s"decls = ${normalizedOwner.unforcedDecls.toList.map(_.debugString).mkString("\n ")}") // !!! DEBUG
//if (base.settings.debug.value) throw new Error()
val stub = name match {
case name: TermName =>
@@ -450,31 +450,6 @@ object Symbols {
*/
def pos: Position = if (coord.isPosition) coord.toPosition else NoPosition
-// -------- GADT handling -----------------------------------------------
-
- /** Perform given operation `op` where this symbol allows tightening of
- * its type bounds.
- */
- private[dotc] def withGADTFlexType[T](op: () => T)(implicit ctx: Context): () => T = { () =>
- assert((denot is TypeParam) && denot.owner.isTerm)
- val saved = denot
- denot = denot.copySymDenotation(initFlags = denot.flags | GADTFlexType)
- try op()
- finally denot = saved
- }
-
- /** Disallow tightening of type bounds for this symbol from now on */
- private[dotc] def resetGADTFlexType()(implicit ctx: Context): Unit = {
- assert(denot is GADTFlexType)
- denot = denot.copySymDenotation(initFlags = denot.flags &~ GADTFlexType)
- }
-
- /** Change info of this symbol to new, tightened type bounds */
- private[core] def changeGADTInfo(bounds: TypeBounds)(implicit ctx: Context): Unit = {
- assert(denot is GADTFlexType)
- denot = denot.copySymDenotation(info = bounds)
- }
-
// -------- Printing --------------------------------------------------------
/** The prefix string to be used when displaying this symbol without denotation */
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 6443c5054..539ef5e0d 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -141,7 +141,7 @@ class TypeApplications(val self: Type) extends AnyVal {
case arg :: args1 =>
if (tparams.isEmpty) {
println(s"applied type mismatch: $self $args, typeParams = $typeParams, tsym = ${self.typeSymbol.debugString}") // !!! DEBUG
- println(s"precomplete decls = ${self.typeSymbol.decls.toList.map(_.denot).mkString("\n ")}")
+ println(s"precomplete decls = ${self.typeSymbol.unforcedDecls.toList.map(_.denot).mkString("\n ")}")
}
val tparam = tparams.head
val arg1 =
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 34f9bfbb9..cae4500e4 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -618,9 +618,12 @@ class TypeComparer(initctx: Context) extends DotClass {
secondTry(OrType.make(derivedRef(tp11), derivedRef(tp12)), tp2)
*/
case TypeBounds(lo1, hi1) =>
- if ((ctx.mode is Mode.GADTflexible) && (tp1.symbol is GADTFlexType) &&
- !isSubTypeWhenFrozen(hi1, tp2))
- trySetType(tp1, TypeBounds(lo1, hi1 & tp2))
+ val gbounds1 = ctx.gadt.bounds(tp1.symbol)
+ if (gbounds1 != null)
+ isSubTypeWhenFrozen(gbounds1.hi, tp2) ||
+ (ctx.mode is Mode.GADTflexible) &&
+ narrowGADTBounds(tp1, TypeBounds(gbounds1.lo, gbounds1.hi & tp2)) ||
+ tryRebase2nd
else if (lo1 eq hi1) isSubType(hi1, tp2)
else tryRebase2nd
case _ =>
@@ -637,9 +640,12 @@ class TypeComparer(initctx: Context) extends DotClass {
}
def compareNamed: Boolean = tp2.info match {
case TypeBounds(lo2, hi2) =>
- if ((ctx.mode is Mode.GADTflexible) && (tp2.symbol is GADTFlexType) &&
- !isSubTypeWhenFrozen(tp1, lo2))
- trySetType(tp2, TypeBounds(lo2 | tp1, hi2))
+ val gbounds2 = ctx.gadt.bounds(tp2.symbol)
+ if (gbounds2 != null)
+ isSubTypeWhenFrozen(tp1, gbounds2.lo) ||
+ (ctx.mode is Mode.GADTflexible) &&
+ narrowGADTBounds(tp2, TypeBounds(gbounds2.lo | tp1, gbounds2.hi)) ||
+ tryRebase3rd
else
((frozenConstraint || !isCappable(tp1)) && isSubType(tp1, lo2)
|| tryRebase3rd)
@@ -912,9 +918,9 @@ class TypeComparer(initctx: Context) extends DotClass {
tp.exists && !tp.isLambda
}
- def trySetType(tr: NamedType, bounds: TypeBounds): Boolean =
+ def narrowGADTBounds(tr: NamedType, bounds: TypeBounds): Boolean =
isSubType(bounds.lo, bounds.hi) &&
- { tr.symbol.changeGADTInfo(bounds); true }
+ { ctx.gadt.setBounds(tr.symbol, bounds); true }
// Tests around `matches`
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index 8190b8cb6..260e2f6d6 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package core
import Contexts._, Types._, Symbols._, Names._, Flags._, Scopes._
-import SymDenotations._
+import SymDenotations._, Denotations.Denotation
import config.Printers._
import Decorators._
import StdNames._
@@ -224,6 +224,25 @@ trait TypeOps { this: Context =>
cls.enter(sym, decls)
}
+ /** If `tpe` is of the form `p.x` where `p` refers to a package
+ * but `x` is not owned by a package, expand it to
+ *
+ * p.package.x
+ */
+ def makePackageObjPrefixExplicit(tpe: NamedType): Type = {
+ def tryInsert(pkgClass: SymDenotation): Type = pkgClass match {
+ case pkgCls: PackageClassDenotation if !(tpe.symbol.maybeOwner is Package) =>
+ tpe.derivedSelect(pkgCls.packageObj.valRef)
+ case _ =>
+ tpe
+ }
+ tpe.prefix match {
+ case pre: ThisType if pre.cls is Package => tryInsert(pre.cls)
+ case pre: TermRef if pre.symbol is Package => tryInsert(pre.symbol.moduleClass)
+ case _ => tpe
+ }
+ }
+
/** If we have member definitions
*
* type argSym v= from
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index a1ca7796f..e520ea172 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -895,7 +895,7 @@ object Types {
* no symbol it tries `member` as an alternative.
*/
def typeParamNamed(name: TypeName)(implicit ctx: Context): Symbol =
- classSymbol.decls.lookup(name) orElse member(name).symbol
+ classSymbol.unforcedDecls.lookup(name) orElse member(name).symbol
/** If this is a prototype with some ignored component, reveal one more
* layer of it. Otherwise the type itself.
@@ -2515,10 +2515,7 @@ object Types {
object TypeAlias {
def apply(alias: Type, variance: Int = 0)(implicit ctx: Context) =
ctx.uniqueTypeAliases.enterIfNew(alias, variance)
- def unapply(tp: TypeAlias): Option[Type] = tp match {
- case tp: TypeAlias => Some(tp.alias)
- case _ => None
- }
+ def unapply(tp: TypeAlias): Option[Type] = Some(tp.alias)
}
// ----- Annotated and Import types -----------------------------------------------
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index cc3d3eb7f..a8be0bb94 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -368,7 +368,7 @@ class ClassfileParser(
val s = ctx.newSymbol(
owner, expname, owner.typeParamCreationFlags,
typeParamCompleter(index), coord = indexCoord(index))
- if (owner.isClass) owner.asClass.enter(s, owner.decls)
+ if (owner.isClass) owner.asClass.enter(s)
tparams = tparams + (tpname -> s)
sig2typeBounds(tparams, skiptvs = true)
newTParams += s
@@ -553,12 +553,15 @@ class ClassfileParser(
newType
}
- /** Add a synthetic constructor and potentially also default getters which
+ /** Add synthetic constructor(s) and potentially also default getters which
* reflects the fields of the annotation with given `classInfo`.
* Annotations in Scala are assumed to get all their arguments as constructor
* parameters. For Java annotations we need to fake it by making up the constructor.
* Note that default getters have type Nothing. That's OK because we need
* them only to signal that the corresponding parameter is optional.
+ * If the constructor takes as last parameter an array, it can also accept
+ * a vararg argument. We solve this by creating two constructors, one with
+ * an array, the other with a repeated parameter.
*/
def addAnnotationConstructor(classInfo: Type, tparams: List[Symbol] = Nil)(implicit ctx: Context): Unit = {
def addDefaultGetter(attr: Symbol, n: Int) =
@@ -574,21 +577,33 @@ class ClassfileParser(
case classInfo: TempClassInfoType =>
val attrs = classInfo.decls.toList.filter(_.isTerm)
val targs = tparams.map(_.typeRef)
- val methType = MethodType(
- attrs.map(_.name.asTermName),
- attrs.map(_.info.resultType),
- classRoot.typeRef.appliedTo(targs))
- val constr = ctx.newSymbol(
+ val paramNames = attrs.map(_.name.asTermName)
+ val paramTypes = attrs.map(_.info.resultType)
+
+ def addConstr(ptypes: List[Type]) = {
+ val mtype = MethodType(paramNames, ptypes, classRoot.typeRef.appliedTo(targs))
+ val constrType = if (tparams.isEmpty) mtype else TempPolyType(tparams, mtype)
+ val constr = ctx.newSymbol(
owner = classRoot.symbol,
name = nme.CONSTRUCTOR,
flags = Flags.Synthetic,
- info = if (tparams.isEmpty) methType else TempPolyType(tparams, methType)
+ info = constrType
).entered
- for ((attr, i) <- attrs.zipWithIndex)
- if (attr.hasAnnotation(defn.AnnotationDefaultAnnot)) {
- constr.setFlag(Flags.HasDefaultParams)
- addDefaultGetter(attr, i)
- }
+ for ((attr, i) <- attrs.zipWithIndex)
+ if (attr.hasAnnotation(defn.AnnotationDefaultAnnot)) {
+ constr.setFlag(Flags.HasDefaultParams)
+ addDefaultGetter(attr, i)
+ }
+ }
+
+ addConstr(paramTypes)
+ if (paramTypes.nonEmpty)
+ paramTypes.last match {
+ case defn.ArrayType(elemtp) =>
+ addConstr(paramTypes.init :+ defn.RepeatedParamType.appliedTo(elemtp))
+ case _ =>
+ }
+
}
}
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index 728048700..f7aef3aaf 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -343,7 +343,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
if (denot.exists && !denot1.exists) { // !!!DEBUG
val alts = denot.alternatives map (d => d+":"+d.info+"/"+d.signature)
System.err.println(s"!!! disambiguation failure: $alts")
- val members = denot.alternatives.head.symbol.owner.decls.toList map (d => d+":"+d.info+"/"+d.signature)
+ val members = denot.alternatives.head.symbol.owner.info.decls.toList map (d => d+":"+d.info+"/"+d.signature)
System.err.println(s"!!! all members: $members")
}
if (tag == EXTref) sym else sym.moduleClass
@@ -445,7 +445,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
)
owner.asClass.enter(sym, symScope(owner))
else if (isRefinementClass(owner))
- symScope(owner).asInstanceOf[MutableScope].enter(sym)
+ symScope(owner).openForMutations.enter(sym)
sym
}
@@ -475,7 +475,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
val unpickler = new LocalUnpickler() withDecls symScope(cls)
if (flags is ModuleClass)
unpickler withSourceModule (implicit ctx =>
- cls.owner.decls.lookup(cls.name.sourceModuleName)
+ cls.owner.info.decls.lookup(cls.name.sourceModuleName)
.suchThat(_ is Module).symbol)
else unpickler
}
@@ -637,7 +637,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
// and also for the inner Transform class in all views. We fix it by
// replacing the this with the appropriate super.
if (sym.owner != thispre.cls) {
- val overriding = thispre.cls.decls.lookup(sym.name)
+ val overriding = thispre.cls.info.decls.lookup(sym.name)
if (overriding.exists && overriding != sym) {
val base = pre.baseTypeWithArgs(sym.owner)
assert(base.exists)
diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala
index dc6d8c6ab..41f007e66 100644
--- a/src/dotty/tools/dotc/reporting/Reporter.scala
+++ b/src/dotty/tools/dotc/reporting/Reporter.scala
@@ -101,16 +101,12 @@ trait Reporting { this: Context =>
def incompleteInputError(msg: String, pos: SourcePosition = NoSourcePosition)(implicit ctx: Context): Unit =
reporter.incomplete(new Error(msg, pos))(ctx)
- /** Log msg if current phase or its precedessor is mentioned in
- * settings.log.
- * The reason we also pick the predecessor is that during the
- * tree transform of phase X, we often are already in phase X+1.
- * It's convenient to have logging work independently of whether
- * we have advanced the phase or not.
+ /** Log msg if settings.log contains the current phase.
+ * See [[config.CompilerCommand#explainAdvanced]] for the exact meaning of
+ * "contains" here.
*/
def log(msg: => String): Unit =
- if (this.settings.log.value.containsPhase(phase) ||
- this.settings.log.value.containsPhase(phase.prev))
+ if (this.settings.log.value.containsPhase(phase))
echo(s"[log ${ctx.phasesStack.reverse.mkString(" -> ")}] $msg")
def debuglog(msg: => String): Unit =
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index 933252ccd..a0370feca 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -443,7 +443,7 @@ object Erasure extends TypeTestsCasts{
if (isRequired) {
// check for clashes
- val clash: Option[Symbol] = oldSymbol.owner.decls.lookupAll(bridge.name).find {
+ val clash: Option[Symbol] = oldSymbol.owner.info.decls.lookupAll(bridge.name).find {
sym =>
(sym.name eq bridge.name) && sym.info.widen =:= bridge.info.widen
}.orElse(
diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala
index c8dacd1d7..1363615a5 100644
--- a/src/dotty/tools/dotc/transform/LambdaLift.scala
+++ b/src/dotty/tools/dotc/transform/LambdaLift.scala
@@ -275,7 +275,7 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
initFlags = local.flags | Private | maybeStatic | maybeNotJavaPrivate,
info = liftedInfo(local)).installAfter(thisTransform)
if (local.isClass)
- for (member <- local.asClass.decls)
+ for (member <- local.asClass.info.decls)
if (member.isConstructor) {
val linfo = liftedInfo(member)
if (linfo ne member.info)
diff --git a/src/dotty/tools/dotc/transform/Mixin.scala b/src/dotty/tools/dotc/transform/Mixin.scala
index 230763fae..7e307c736 100644
--- a/src/dotty/tools/dotc/transform/Mixin.scala
+++ b/src/dotty/tools/dotc/transform/Mixin.scala
@@ -148,13 +148,13 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
ctx.atPhase(thisTransform) { implicit ctx => sym is Deferred }
def traitInits(mixin: ClassSymbol): List[Tree] =
- for (getter <- mixin.decls.filter(getr => getr.isGetter && !wasDeferred(getr)).toList)
+ for (getter <- mixin.info.decls.filter(getr => getr.isGetter && !wasDeferred(getr)).toList)
yield {
DefDef(implementation(getter.asTerm), superRef(initializer(getter)).appliedToNone)
}
def setters(mixin: ClassSymbol): List[Tree] =
- for (setter <- mixin.decls.filter(setr => setr.isSetter && !wasDeferred(setr)).toList)
+ for (setter <- mixin.info.decls.filter(setr => setr.isSetter && !wasDeferred(setr)).toList)
yield DefDef(implementation(setter.asTerm), unitLiteral.withPos(cls.pos))
cpy.Template(impl)(
diff --git a/src/dotty/tools/dotc/transform/OverridingPairs.scala b/src/dotty/tools/dotc/transform/OverridingPairs.scala
index bc3c085a9..f631dcf9a 100644
--- a/src/dotty/tools/dotc/transform/OverridingPairs.scala
+++ b/src/dotty/tools/dotc/transform/OverridingPairs.scala
@@ -53,7 +53,7 @@ object OverridingPairs {
def fillDecls(bcs: List[Symbol], deferred: Boolean): Unit = bcs match {
case bc :: bcs1 =>
fillDecls(bcs1, deferred)
- var e = bc.info.decls.asInstanceOf[MutableScope].lastEntry
+ var e = bc.info.decls.lastEntry
while (e != null) {
if (e.sym.is(Deferred) == deferred && !exclude(e.sym))
decls.enter(e.sym)
diff --git a/src/dotty/tools/dotc/transform/ResolveSuper.scala b/src/dotty/tools/dotc/transform/ResolveSuper.scala
index 9f952f6de..953c8b74d 100644
--- a/src/dotty/tools/dotc/transform/ResolveSuper.scala
+++ b/src/dotty/tools/dotc/transform/ResolveSuper.scala
@@ -75,7 +75,7 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
import ops._
def superAccessors(mixin: ClassSymbol): List[Tree] =
- for (superAcc <- mixin.decls.filter(_ is SuperAccessor).toList)
+ for (superAcc <- mixin.info.decls.filter(_ is SuperAccessor).toList)
yield polyDefDef(implementation(superAcc.asTerm), forwarder(rebindSuper(cls, superAcc)))
def methodOverrides(mixin: ClassSymbol): List[Tree] = {
@@ -84,7 +84,7 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
meth.is(Method, butNot = PrivateOrDeferred) &&
!isOverridden(meth) &&
!meth.allOverriddenSymbols.forall(_ is Deferred)
- for (meth <- mixin.decls.toList if needsDisambiguation(meth))
+ for (meth <- mixin.info.decls.toList if needsDisambiguation(meth))
yield polyDefDef(implementation(meth.asTerm), forwarder(meth))
}
diff --git a/src/dotty/tools/dotc/transform/SuperAccessors.scala b/src/dotty/tools/dotc/transform/SuperAccessors.scala
index f727201b2..0d89e9d74 100644
--- a/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -146,7 +146,7 @@ class SuperAccessors extends MacroTransform with IdentityDenotTransformer { this
if (needsExpansion(s)) {
ctx.deprecationWarning(s"private qualified with a class has been deprecated, use package enclosing ${s.privateWithin} instead", s.pos)
/* disabled for now
- decls.asInstanceOf[MutableScope].unlink(s)
+ decls.openForMutations.unlink(s)
s.copySymDenotation(name = s.name.expandedName(s.privateWithin))
.installAfter(thisTransformer)
decls1.enter(s)(nextCtx)
diff --git a/src/dotty/tools/dotc/transform/SymUtils.scala b/src/dotty/tools/dotc/transform/SymUtils.scala
index 9274150b1..0a5854ea7 100644
--- a/src/dotty/tools/dotc/transform/SymUtils.scala
+++ b/src/dotty/tools/dotc/transform/SymUtils.scala
@@ -80,7 +80,7 @@ class SymUtils(val self: Symbol) extends AnyVal {
self.owner.info.decl(name).suchThat(_ is Accessor).symbol
def caseAccessors(implicit ctx:Context) =
- self.decls.filter(_ is CaseAccessor).toList
+ self.info.decls.filter(_ is CaseAccessor).toList
def getter(implicit ctx: Context): Symbol =
if (self.isGetter) self else accessorNamed(self.asTerm.name.getterName)
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 86376356c..ea2fd40de 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -27,7 +27,7 @@ trait NamerContextOps { this: Context =>
def enter(sym: Symbol): Symbol = {
ctx.owner match {
case cls: ClassSymbol => cls.enter(sym)
- case _ => this.scope.asInstanceOf[MutableScope].enter(sym)
+ case _ => this.scope.openForMutations.enter(sym)
}
sym
}
@@ -37,7 +37,7 @@ trait NamerContextOps { this: Context =>
if (owner.isClass)
if (outer.owner == owner) { // inner class scope; check whether we are referring to self
if (scope.size == 1) {
- val elem = scope.asInstanceOf[MutableScope].lastEntry
+ val elem = scope.lastEntry
if (elem.name == name) return elem.sym.denot // return self
}
assert(scope.size <= 1, scope)
@@ -52,7 +52,7 @@ trait NamerContextOps { this: Context =>
* the declarations of the current class.
*/
def effectiveScope: Scope =
- if (owner != null && owner.isClass) owner.asClass.decls
+ if (owner != null && owner.isClass) owner.asClass.unforcedDecls
else scope
/** The symbol (stored in some typer's symTree) of an enclosing context definition */
@@ -306,7 +306,7 @@ class Namer { typer: Typer =>
val localCtx: Context = ctx.fresh.setNewScope
selfInfo match {
case sym: Symbol if sym.exists && sym.name != nme.WILDCARD =>
- localCtx.scope.asInstanceOf[MutableScope].enter(sym)
+ localCtx.scope.openForMutations.enter(sym)
case _ =>
}
localCtx
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 445987e0d..f4b0ef4f2 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -112,21 +112,6 @@ trait TypeAssigner {
* that the package object shows up as the prefix.
*/
def ensureAccessible(tpe: Type, superAccess: Boolean, pos: Position)(implicit ctx: Context): Type = {
-
- def tryInsertPackageObj(tpe: NamedType, d: Denotation): Type = {
- def tryInsert(pkgClass: SymDenotation): Type = pkgClass match {
- case pkgCls: PackageClassDenotation if !(d.symbol.maybeOwner is Package) =>
- tpe.derivedSelect(pkgCls.packageObj.valRef)
- case _ =>
- tpe
- }
- tpe.prefix match {
- case pre: ThisType if pre.cls is Package => tryInsert(pre.cls)
- case pre: TermRef if pre.symbol is Package => tryInsert(pre.symbol.moduleClass)
- case _ => tpe
- }
- }
-
def test(tpe: Type, firstTry: Boolean): Type = tpe match {
case tpe: NamedType =>
val pre = tpe.prefix
@@ -159,7 +144,7 @@ trait TypeAssigner {
else if (d.symbol is TypeParamAccessor) // always dereference type param accessors
ensureAccessible(d.info.bounds.hi, superAccess, pos)
else
- tryInsertPackageObj(tpe withDenot d, d)
+ ctx.makePackageObjPrefixExplicit(tpe withDenot d)
case _ =>
tpe
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 5d388e7de..dedff0e3a 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -454,7 +454,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def classLeaks(sym: ClassSymbol): Boolean =
(ctx.owner is Method) || // can't hoist classes out of method bodies
(sym.info.parents exists typeLeaks) ||
- (sym.decls.toList exists (t => typeLeaks(t.info)))
+ (sym.info.decls.toList exists (t => typeLeaks(t.info)))
leakingTypes(block.tpe)
}
@@ -628,10 +628,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedCases(cases: List[untpd.CaseDef], selType: Type, pt: Type)(implicit ctx: Context) = {
/** gadtSyms = "all type parameters of enclosing methods that appear
- * non-variantly in the selector type" todo: should typevars
- * which appear with variances +1 and -1 (in different
- * places) be considered as well?
- */
+ * non-variantly in the selector type" todo: should typevars
+ * which appear with variances +1 and -1 (in different
+ * places) be considered as well?
+ */
val gadtSyms: Set[Symbol] = ctx.traceIndented(i"GADT syms of $selType", gadts) {
val accu = new TypeAccumulator[Set[Symbol]] {
def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = {
@@ -650,9 +650,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
cases mapconserve (typedCase(_, pt, selType, gadtSyms))
}
+ /** Type a case. Overridden in ReTyper, that's why it's separate from
+ * typedCases.
+ */
def typedCase(tree: untpd.CaseDef, pt: Type, selType: Type, gadtSyms: Set[Symbol])(implicit ctx: Context): CaseDef = track("typedCase") {
+ val originalCtx = ctx
+
def caseRest(pat: Tree)(implicit ctx: Context) = {
- gadtSyms foreach (_.resetGADTFlexType)
pat foreachSubTree {
case b: Bind =>
if (ctx.scope.lookup(b.name) == NoSymbol) ctx.enter(b.symbol)
@@ -661,11 +665,21 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
val guard1 = typedExpr(tree.guard, defn.BooleanType)
val body1 = typedExpr(tree.body, pt)
+ .ensureConforms(pt)(originalCtx) // insert a cast if body does not conform to expected type if we disregard gadt bounds
assignType(cpy.CaseDef(tree)(pat, guard1, body1), body1)
}
- val doCase: () => CaseDef =
- () => caseRest(typedPattern(tree.pat, selType))(ctx.fresh.setNewScope)
- (doCase /: gadtSyms)((op, tsym) => tsym.withGADTFlexType(op))()
+
+ val gadtCtx =
+ if (gadtSyms.isEmpty) ctx
+ else {
+ val c = ctx.fresh.setFreshGADTBounds
+ for (sym <- gadtSyms)
+ if (!c.gadt.bounds.contains(sym))
+ c.gadt.setBounds(sym, TypeBounds.empty)
+ c
+ }
+ val pat1 = typedPattern(tree.pat, selType)(gadtCtx)
+ caseRest(pat1)(gadtCtx.fresh.setNewScope)
}
def typedReturn(tree: untpd.Return)(implicit ctx: Context): Return = track("typedReturn") {
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index b156d8878..3f1170e40 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -68,6 +68,7 @@ class tests extends CompilerTest {
@Test def pos_nullarify = compileFile(posDir, "nullarify", "-Ycheck:nullarify" :: Nil)
@Test def pos_subtyping = compileFile(posDir, "subtyping")
@Test def pos_t2613 = compileFile(posSpecialDir, "t2613")(allowDeepSubtypes)
+ @Test def pos_packageObj = compileFile(posDir, "i0239")
@Test def pos_all = compileFiles(posDir, failedOther)
diff --git a/test/test/DottyTest.scala b/test/test/DottyTest.scala
index 90a0154ec..21eebd660 100644
--- a/test/test/DottyTest.scala
+++ b/test/test/DottyTest.scala
@@ -14,7 +14,7 @@ import dotty.tools.dotc.Compiler
import dotty.tools.dotc
import dotty.tools.dotc.core.Phases.Phase
-class DottyTest extends ContextEscapeDetection{
+class DottyTest /*extends ContextEscapeDetection*/ {
dotty.tools.dotc.parsing.Scanners // initialize keywords
@@ -36,11 +36,12 @@ class DottyTest extends ContextEscapeDetection{
base.definitions.init(ctx)
ctx
}
-
+/*
override def getCtx: Context = ctx
override def clearCtx() = {
ctx = null
}
+*/
private def compilerWithChecker(phase: String)(assertion:(tpd.Tree, Context) => Unit) = new Compiler {
self =>
override def phases = {
diff --git a/tests/pending/pos/annot.scala b/tests/pending/pos/annot.scala
deleted file mode 100644
index 8e21803b4..000000000
--- a/tests/pending/pos/annot.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-class Test {
-
- @SuppressWarnings("hi") def foo() = ???
-
-}
diff --git a/tests/pos/annot-bootstrap.scala b/tests/pos/annot-bootstrap.scala
new file mode 100644
index 000000000..bef877dcd
--- /dev/null
+++ b/tests/pos/annot-bootstrap.scala
@@ -0,0 +1,8 @@
+package scala.annotation.unchecked
+
+// note: if the case class is not inside an object, the error disappears
+object test {
+ case class L(a: Int)
+}
+
+final class uncheckedVariance extends scala.annotation.StaticAnnotation {}
diff --git a/tests/pos/annot.scala b/tests/pos/annot.scala
index ab80aba27..c3a17ff1d 100644
--- a/tests/pos/annot.scala
+++ b/tests/pos/annot.scala
@@ -2,11 +2,11 @@ import java.beans.Transient
class Test {
- @SuppressWarnings(Array("hi")) def foo() = ??? // evalutation of annotation on type cannot be deffered as requires implicit resolution(only generic Array$.apply applies here)
+ @SuppressWarnings(Array("hi")) def foo() = ??? // evalutation of annotation on type cannot be deferred as requires implicit resolution(only generic Array$.apply applies here)
- @SuppressWarnings(Array("hi", "foo")) def foo2() = ??? //can be deffered as there is a non-generic method
+ @SuppressWarnings(Array("hi", "foo")) def foo2() = ??? //can be deferred as there is a non-generic method
-// @SuppressWarnings("hi") def foo3() = ??? // can be written in java and is serialized this way in bytecode. doesn't typecheck
+ @SuppressWarnings("hi") def foo3() = ??? // can be written in java and is serialized this way in bytecode. doesn't typecheck
@Transient(false) def bar = ???
diff --git a/tests/pos/i0268.scala b/tests/pos/i0268.scala
new file mode 100644
index 000000000..6ac0c5c90
--- /dev/null
+++ b/tests/pos/i0268.scala
@@ -0,0 +1,15 @@
+package typespatmat
+
+sealed trait Box2[T]
+final case class Int2(x: Int) extends Box2[Int]
+final case class Str2(x: String)
+ extends Box2[String]
+final case class Gen[T](x: T) extends Box2[T]
+
+object Box2 {
+ def double2[T](x: Box2[T]): T = x match {
+ case Int2(i) => i * 2
+ case Str2(s) => s + s
+ case Gen(x) => x
+ }
+}