aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dotty/runtime/Arrays.scala11
-rw-r--r--src/dotty/runtime/LazyHolders.scala44
-rw-r--r--src/dotty/tools/backend/jvm/DottyBackendInterface.scala3
-rw-r--r--src/dotty/tools/dotc/Compiler.scala5
-rw-r--r--src/dotty/tools/dotc/ast/TreeTypeMap.scala2
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala2
-rw-r--r--src/dotty/tools/dotc/core/Scopes.scala10
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala2
-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.scala6
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala2
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala48
-rw-r--r--src/dotty/tools/dotc/core/Types.scala44
-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/printing/PlainPrinter.scala2
-rw-r--r--src/dotty/tools/dotc/transform/ElimRepeated.scala32
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala2
-rw-r--r--src/dotty/tools/dotc/transform/FullParameterization.scala24
-rw-r--r--src/dotty/tools/dotc/transform/Getters.scala2
-rw-r--r--src/dotty/tools/dotc/transform/LambdaLift.scala2
-rw-r--r--src/dotty/tools/dotc/transform/LazyVals.scala83
-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/transform/TailRec.scala40
-rw-r--r--src/dotty/tools/dotc/typer/ErrorReporting.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala36
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala1
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala9
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala2
35 files changed, 332 insertions, 194 deletions
diff --git a/src/dotty/runtime/Arrays.scala b/src/dotty/runtime/Arrays.scala
index e7f819df8..5767991e5 100644
--- a/src/dotty/runtime/Arrays.scala
+++ b/src/dotty/runtime/Arrays.scala
@@ -2,7 +2,7 @@ package dotty.runtime
import scala.reflect.ClassTag
-/** All but the first operation should be short-circuited and implemented specially by
+/** All but the first two operations should be short-circuited and implemented specially by
* the backend.
*/
object Arrays {
@@ -12,7 +12,14 @@ object Arrays {
*/
def newGenericArray[T](length: Int)(implicit tag: ClassTag[T]): Array[T] =
tag.newArray(length)
-
+
+ /** Convert a sequence to a Java array with element type given by `clazz`. */
+ def seqToArray[T](xs: Seq[T], clazz: Class[_]): Array[T] = {
+ val arr = java.lang.reflect.Array.newInstance(clazz, xs.length).asInstanceOf[Array[T]]
+ xs.copyToArray(arr)
+ arr
+ }
+
/** Create an array of type T. T must be of form Array[E], with
* E being a reference type.
*/
diff --git a/src/dotty/runtime/LazyHolders.scala b/src/dotty/runtime/LazyHolders.scala
index 86c5d34ec..1e31cda66 100644
--- a/src/dotty/runtime/LazyHolders.scala
+++ b/src/dotty/runtime/LazyHolders.scala
@@ -3,38 +3,42 @@ package dotty.runtime
/**
* Classes used as holders for local lazy vals
*/
-class LazyInt(init: => Int) {
- lazy val value = init
+class LazyInt {
+ var value: Int = _
+ @volatile var initialized: Boolean = false
}
-class LazyLong(init: => Long) {
- lazy val value = init
+class LazyLong {
+ var value: Long = _
+ @volatile var initialized: Boolean = false
}
-class LazyBoolean(init: => Boolean) {
- lazy val value = init
+class LazyBoolean {
+ var value: Boolean = _
+ @volatile var initialized: Boolean = false
}
-class LazyDouble(init: => Double) {
- lazy val value = init
+class LazyDouble {
+ var value: Double = _
+ @volatile var initialized: Boolean = false
}
-class LazyFloat(init: => Float) {
- lazy val value = init
+class LazyByte {
+ var value: Byte = _
+ @volatile var initialized: Boolean = false
}
-class LazyByte(init: => Byte) {
- lazy val value = init
+class LazyRef {
+ var value: AnyRef = _
+ @volatile var initialized: Boolean = false
}
-class LazyRef(init: => AnyRef) {
- lazy val value = init
+class LazyShort {
+ var value: Short = _
+ @volatile var initialized: Boolean = false
}
-class LazyShort(init: => Short) {
- lazy val value = init
-}
-
-class LazyChar(init: => Char) {
- lazy val value = init
+class LazyChar {
+ var value: Char = _
+ @volatile var initialized: Boolean = false
}
diff --git a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
index 672e00a5c..14408ce7d 100644
--- a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
+++ b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
@@ -282,6 +282,9 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
Some(tpd.ref(prefix).select(i.symbol))
case TermRef(prefix: ThisType, name) =>
Some(tpd.This(prefix.cls).select(i.symbol))
+ case TermRef(NoPrefix, name) =>
+ if(i.symbol is Flags.Method) Some(This(i.symbol.enclosingClass).select(i.symbol)) // workaround #342 todo: remove after fixed
+ else None
case _ => None
}
}
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index c5c1d8713..721b52b2e 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -52,7 +52,8 @@ class Compiler {
List(new PatternMatcher,
new ExplicitOuter,
new Splitter),
- List(new ElimByName,
+ List(new LazyVals,
+ new ElimByName,
new SeqLiterals,
new InterceptedMethods,
new Literalize,
@@ -60,7 +61,7 @@ class Compiler {
new ResolveSuper),
List(new Erasure),
List(new Mixin,
- new Memoize, // TODO: Make LazyVals a part of this phase
+ new Memoize,
new CapturedVars,
new Constructors),
List(new LambdaLift,
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/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/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/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala
index 27aa00392..b7cc1e03f 100644
--- a/src/dotty/tools/dotc/core/StdNames.scala
+++ b/src/dotty/tools/dotc/core/StdNames.scala
@@ -226,6 +226,7 @@ object StdNames {
val FAKE_LOCAL_THIS: N = "this$"
val IMPLCLASS_CONSTRUCTOR: N = "$init$"
val LAZY_LOCAL: N = "$lzy"
+ val LAZY_LOCAL_INIT: N = "$lzyINIT"
val LAZY_FIELD_OFFSET: N = "OFFSET$"
val LAZY_SLOW_SUFFIX: N = "$lzycompute"
val LOCAL_SUFFIX: N = "$$local"
@@ -469,6 +470,7 @@ object StdNames {
val selectTerm: N = "selectTerm"
val selectType: N = "selectType"
val self: N = "self"
+ val seqToArray: N = "seqToArray"
val setAccessible: N = "setAccessible"
val setAnnotations: N = "setAnnotations"
val setSymbol: N = "setSymbol"
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index c8fbb3d03..6b3532944 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 {
@@ -239,24 +239,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 ----------------------------------------------
@@ -1002,7 +1009,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
@@ -1233,7 +1240,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)
@@ -1263,7 +1270,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
}
@@ -1274,7 +1281,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)
@@ -1286,7 +1293,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)
}
@@ -1316,7 +1323,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 {
@@ -1463,14 +1470,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 bff743fea..f6e4119ea 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -25,7 +25,7 @@ import Denotations.{ Denotation, SingleDenotation, MultiDenotation }
import collection.mutable
import io.AbstractFile
import language.implicitConversions
-import util.DotClass
+import util.{NoSource, DotClass}
/** Creation methods for symbols */
trait Symbols { this: Context =>
@@ -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 =>
@@ -518,6 +518,8 @@ object Symbols {
object NoSymbol extends Symbol(NoCoord) {
denot = NoDenotation
+
+ override def associatedFile(implicit ctx: Context): AbstractFile = NoSource.file
}
implicit class Copier[N <: Name](sym: Symbol { type ThisName = N })(implicit ctx: Context) {
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index e59c60959..998b4f944 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 9826a23ea..b40baafdf 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -41,7 +41,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
result
}
- /** For stastics: count how many isSubTypes are part of succesful comparisons */
+ /** For statistics: count how many isSubTypes are part of successful comparisons */
private var successCount = 0
private var totalCount = 0
@@ -140,21 +140,14 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
private def firstTry(tp1: Type, tp2: Type): Boolean = tp2 match {
case tp2: NamedType =>
- def compareHKOrAlias(info1: Type) =
- tp2.name == tpnme.Apply && {
- val lambda2 = tp2.prefix.LambdaClass(forcing = true)
- lambda2.exists && !tp1.isLambda &&
- tp1.testLifted(lambda2.typeParams, isSubType(_, tp2.prefix))
- } || {
- tp2.info match {
- case info2: TypeAlias => isSubType(tp1, info2.alias)
- case _ => info1 match {
- case info1: TypeAlias => isSubType(info1.alias, tp2)
- case NoType => secondTry(tp1, tp2)
- case _ => thirdTryNamed(tp1, tp2)
- }
- }
+ def compareAlias(info1: Type) = tp2.info match {
+ case info2: TypeAlias => isSubType(tp1, info2.alias)
+ case _ => info1 match {
+ case info1: TypeAlias => isSubType(info1.alias, tp2)
+ case NoType => secondTry(tp1, tp2)
+ case _ => thirdTryNamed(tp1, tp2)
}
+ }
def compareNamed = {
implicit val ctx: Context = this.ctx // Dotty deviation: implicits need explicit type
tp1 match {
@@ -183,9 +176,12 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
!tp1.isInstanceOf[WithFixedSym] &&
!tp2.isInstanceOf[WithFixedSym]
) ||
- compareHKOrAlias(tp1.info)
+ compareHK(tp1, tp2, inOrder = true) ||
+ compareHK(tp2, tp1, inOrder = false) ||
+ compareAlias(tp1.info)
case _ =>
- compareHKOrAlias(NoType)
+ compareHK(tp2, tp1, inOrder = false) ||
+ compareAlias(NoType)
}
}
compareNamed
@@ -243,7 +239,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
case tp1: NamedType =>
tp1.info match {
case info1: TypeAlias => isSubType(info1.alias, tp2)
- case _ => thirdTry(tp1, tp2)
+ case _ => compareHK(tp1, tp2, inOrder = true) || thirdTry(tp1, tp2)
+ // Note: If we change the order here, doing compareHK first and following aliases second,
+ // we get a -Ycheck error when compiling dotc/transform. Need to investigate.
}
case tp1: PolyParam =>
def flagNothingBound = {
@@ -460,6 +458,18 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
false
}
+ /** If `projection` is of the form T # Apply where `T` is an instance of a Lambda class,
+ * and `other` is not a type lambda projection, then convert `other` to a type lambda `U`, and
+ * continue with `T <:< U` if `inOrder` is true and `U <:< T` otherwise.
+ */
+ def compareHK(projection: NamedType, other: Type, inOrder: Boolean) =
+ projection.name == tpnme.Apply && {
+ val lambda = projection.prefix.LambdaClass(forcing = true)
+ lambda.exists && !other.isLambda &&
+ other.testLifted(lambda.typeParams,
+ if (inOrder) isSubType(projection.prefix, _) else isSubType(_, projection.prefix))
+ }
+
/** Returns true iff either `tp11 <:< tp21` or `tp12 <:< tp22`, trying at the same time
* to keep the constraint as wide as possible. Specifically, if
*
@@ -524,7 +534,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling wi
case mbr: SingleDenotation => qualifies(mbr)
case _ => mbr hasAltWith qualifies
}
- /*>|>*/ ctx.traceIndented(i"hasMatchingMember($tp1 . $name :? ${tp2.refinedInfo}) ${tp1.member(name).info.show} $rinfo2", subtyping) /*<|<*/ {
+ /*>|>*/ ctx.traceIndented(i"hasMatchingMember($base . $name :? ${tp2.refinedInfo}) ${base.member(name).info.show} $rinfo2", subtyping) /*<|<*/ {
memberMatches(base member name) ||
tp1.isInstanceOf[SingletonType] &&
{ // special case for situations like:
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index e986e680d..6c87d44e6 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -419,6 +419,8 @@ object Types {
if mt.paramTypes.isEmpty && (tp.symbol is Stable) => mt.resultType
case tp1 => tp1
})
+ case tp: PolyParam =>
+ goParam(tp)
case tp: TypeProxy =>
go(tp.underlying)
case tp: ClassInfo =>
@@ -460,6 +462,16 @@ object Types {
// loadClassWithPrivateInnerAndSubSelf in ShowClassTests
go(tp.cls.typeRef) orElse d
}
+ def goParam(tp: PolyParam) = {
+ val next = tp.underlying
+ ctx.typerState.constraint.entry(tp) match {
+ case bounds: TypeBounds if bounds ne next =>
+ ctx.typerState.ephemeral = true
+ go(bounds.hi)
+ case _ =>
+ go(next)
+ }
+ }
def goAnd(l: Type, r: Type) = go(l) & (go(r), pre)
def goOr(l: Type, r: Type) = go(l) | (go(r), pre)
go(this)
@@ -581,7 +593,7 @@ object Types {
}
/** Is this type close enough to that type so that members
- * with the two type would override each other?d
+ * with the two types would override each other?
* This means:
* - Either both types are polytypes with the same number of
* type parameters and their result types match after renaming
@@ -668,14 +680,14 @@ object Types {
case _ => this
}
- /** Widen type if it is unstable (i.e. an EpxprType, or Termref to unstable symbol */
+ /** Widen type if it is unstable (i.e. an ExprType, or TermRef to unstable symbol */
final def widenIfUnstable(implicit ctx: Context): Type = stripTypeVar match {
case tp: ExprType => tp.resultType.widenIfUnstable
case tp: TermRef if !tp.symbol.isStable => tp.underlying.widenIfUnstable
case _ => this
}
- /** Follow aliases and derefernces LazyRefs and instantiated TypeVars until type
+ /** Follow aliases and dereferences LazyRefs and instantiated TypeVars until type
* is no longer alias type, LazyRef, or instantiated type variable.
*/
final def dealias(implicit ctx: Context): Type = this match {
@@ -694,7 +706,7 @@ object Types {
case tp => tp
}
- /** Peform successive widenings and dealiasings until none can be applied anymore */
+ /** Perform successive widenings and dealiasings until none can be applied anymore */
final def widenDealias(implicit ctx: Context): Type = {
val res = this.widen.dealias
if (res eq this) res else res.widenDealias
@@ -891,7 +903,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.
@@ -916,9 +928,9 @@ object Types {
}
/** Same as `subst` but follows aliases as a fallback. When faced with a reference
- * to an alias type, where normal substiution does not yield a new type, the
+ * to an alias type, where normal substitution does not yield a new type, the
* substitution is instead applied to the alias. If that yields a new type,
- * this type is returned, outherwise the original type (not the alias) is returned.
+ * this type is returned, otherwise the original type (not the alias) is returned.
* A use case for this method is if one wants to substitute the type parameters
* of a class and also wants to substitute any parameter accessors that alias
* the type parameters.
@@ -1141,7 +1153,7 @@ object Types {
def map(tm: TypeMap)(implicit ctx: Context): ProtoType
}
- /** Implementations of this trait cache the resukts of `narrow`. */
+ /** Implementations of this trait cache the results of `narrow`. */
trait NarrowCached extends Type {
private var myNarrow: TermRef = null
override def narrow(implicit ctx: Context): TermRef = {
@@ -1182,7 +1194,7 @@ object Types {
* timing dependent. It should only be used if the outcome of the
* essential computation does not depend on the symbol being present or not.
* It's currently used to take an optimized path in substituters and
- * type accumulators, as well as to be safe in diagnostiic printing.
+ * type accumulators, as well as to be safe in diagnostic printing.
* Normally, it's better to use `symbol`, not `currentSymbol`.
*/
def currentSymbol(implicit ctx: Context) =
@@ -2048,6 +2060,7 @@ object Types {
unique(new ImplicitMethodType(paramNames, paramTypes)(resultTypeExp))
}
+ /** A by-name parameter type of the form `=> T`, or the type of a method with no parameter list. */
abstract case class ExprType(override val resultType: Type)
extends CachedProxyType with TermType with MethodicType {
override def underlying(implicit ctx: Context): Type = resultType
@@ -2200,13 +2213,16 @@ object Types {
// ------------ Type variables ----------------------------------------
- /** A type variable is essentially a switch that models some part of a substitution.
+ /** In a TypeApply tree, a TypeVar is created for each argument type to be inferred.
+ * Every type variable is referred to by exactly one inferred type parameter of some
+ * TypeApply tree.
+ *
+ * A type variable is essentially a switch that models some part of a substitution.
* It is first linked to `origin`, a poly param that's in the current constraint set.
* It can then be (once) instantiated to some other type. The instantiation is
* recorded in the type variable itself, or else, if the current type state
* is different from the variable's creation state (meaning unrolls are possible)
- * in the current typer state. Every type variable is referred to by exactly
- * one inferred type parameter in a TypeApply tree.
+ * in the current typer state.
*
* @param origin The parameter that's tracked by the type variable.
* @param creatorState The typer state in which the variable was created.
@@ -2571,7 +2587,7 @@ object Types {
/** The type of an import clause tree */
case class ImportType(expr: Tree) extends UncachedGroundType
- /** Sentinal for "missing type" */
+ /** Sentinel for "missing type" */
case object NoType extends CachedGroundType {
override def exists = false
override def computeHash = hashSeed
@@ -2739,7 +2755,7 @@ object Types {
case tp @ AnnotatedType(annot, underlying) =>
val underlying1 = this(underlying)
- if (underlying1 eq underlying) tp else underlying1
+ if (underlying1 eq underlying) tp else tp.derivedAnnotatedType(mapOver(annot), underlying1)
case tp @ WildcardType =>
tp.derivedWildcardType(mapOver(tp.optBounds))
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 894ad8f80..160bf620c 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -340,7 +340,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
@@ -442,7 +442,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
}
@@ -472,7 +472,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
}
@@ -632,7 +632,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/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 1a6cc77b2..f34135431 100644
--- a/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -371,7 +371,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
def toText(const: Constant): Text = const.tag match {
case StringTag => "\"" + escapedString(const.value.toString) + "\""
- case ClazzTag => "classOf[" ~ toText(const.tpe) ~ "]"
+ case ClazzTag => "classOf[" ~ toText(const.tpe.firstBaseArgInfo(defn.ClassClass)) ~ "]"
case CharTag => s"'${escapedChar(const.charValue)}'"
case LongTag => const.longValue.toString + "L"
case EnumTag => const.symbolValue.name.toString
diff --git a/src/dotty/tools/dotc/transform/ElimRepeated.scala b/src/dotty/tools/dotc/transform/ElimRepeated.scala
index ff56ae872..28131e1e9 100644
--- a/src/dotty/tools/dotc/transform/ElimRepeated.scala
+++ b/src/dotty/tools/dotc/transform/ElimRepeated.scala
@@ -3,12 +3,14 @@ package transform
import core._
import Names._
+import StdNames.nme
import Types._
import dotty.tools.dotc.transform.TreeTransforms.{AnnotationTransformer, TransformerInfo, MiniPhaseTransform, TreeTransformer}
-import ast.Trees.flatten
+import ast.Trees._
import Flags._
import Contexts.Context
import Symbols._
+import Constants._
import Denotations._, SymDenotations._
import Decorators.StringInterpolators
import dotty.tools.dotc.ast.tpd
@@ -56,9 +58,33 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree =
transformTypeOfTree(tree)
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
- transformTypeOfTree(tree) // should also transform the tree if argument needs adaptation
+ override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ val args1 = tree.args.map {
+ case arg: Typed if isWildcardStarArg(arg) =>
+ if (tree.fun.symbol.is(JavaDefined) && arg.expr.tpe.derivesFrom(defn.SeqClass))
+ seqToArray(arg.expr)
+ else arg.expr
+ case arg => arg
+ }
+ transformTypeOfTree(cpy.Apply(tree)(tree.fun, args1))
+ }
+ /** Convert sequence argument to Java array */
+ private def seqToArray(tree: Tree)(implicit ctx: Context): Tree = tree match {
+ case SeqLiteral(elems) =>
+ JavaSeqLiteral(elems)
+ case _ =>
+ val elemType = tree.tpe.firstBaseArgInfo(defn.SeqClass)
+ var elemClass = elemType.classSymbol
+ if (defn.PhantomClasses contains elemClass) elemClass = defn.ObjectClass
+ ref(defn.DottyArraysModule)
+ .select(nme.seqToArray)
+ .appliedToType(elemType)
+ .appliedTo(tree, Literal(Constant(elemClass.typeRef)))
+ .ensureConforms(defn.ArrayType(elemType))
+ // Because of phantomclasses, the Java array's type might not conform to the resturn type
+ }
+
override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree =
transformTypeOfTree(tree)
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/FullParameterization.scala b/src/dotty/tools/dotc/transform/FullParameterization.scala
index 698a57c61..4b205e542 100644
--- a/src/dotty/tools/dotc/transform/FullParameterization.scala
+++ b/src/dotty/tools/dotc/transform/FullParameterization.scala
@@ -85,13 +85,13 @@ trait FullParameterization {
*
* If a self type is present, $this has this self type as its type.
*/
- def fullyParameterizedType(info: Type, clazz: ClassSymbol)(implicit ctx: Context): Type = {
+ def fullyParameterizedType(info: Type, clazz: ClassSymbol, abstractOverClass: Boolean = true)(implicit ctx: Context): Type = {
val (mtparamCount, origResult) = info match {
case info @ PolyType(mtnames) => (mtnames.length, info.resultType)
case info: ExprType => (0, info.resultType)
case _ => (0, info)
}
- val ctparams = clazz.typeParams
+ val ctparams = if(abstractOverClass) clazz.typeParams else Nil
val ctnames = ctparams.map(_.name.unexpandedName())
/** The method result type */
@@ -104,7 +104,7 @@ trait FullParameterization {
/** Replace class type parameters by the added type parameters of the polytype `pt` */
def mapClassParams(tp: Type, pt: PolyType): Type = {
val classParamsRange = (mtparamCount until mtparamCount + ctparams.length).toList
- tp.substDealias(clazz.typeParams, classParamsRange map (PolyParam(pt, _)))
+ tp.substDealias(ctparams, classParamsRange map (PolyParam(pt, _)))
}
/** The bounds for the added type paraneters of the polytype `pt` */
@@ -141,19 +141,23 @@ trait FullParameterization {
/** The type parameters (skolems) of the method definition `originalDef`,
* followed by the class parameters of its enclosing class.
*/
- private def allInstanceTypeParams(originalDef: DefDef)(implicit ctx: Context): List[Symbol] =
- originalDef.tparams.map(_.symbol) ::: originalDef.symbol.enclosingClass.typeParams
+ private def allInstanceTypeParams(originalDef: DefDef, abstractOverClass: Boolean)(implicit ctx: Context): List[Symbol] =
+ if (abstractOverClass)
+ originalDef.tparams.map(_.symbol) ::: originalDef.symbol.enclosingClass.typeParams
+ else originalDef.tparams.map(_.symbol)
/** Given an instance method definition `originalDef`, return a
* fully parameterized method definition derived from `originalDef`, which
* has `derived` as symbol and `fullyParameterizedType(originalDef.symbol.info)`
* as info.
+ * `abstractOverClass` defines weather the DefDef should abstract over type parameters
+ * of class that contained original defDef
*/
- def fullyParameterizedDef(derived: TermSymbol, originalDef: DefDef)(implicit ctx: Context): Tree =
+ def fullyParameterizedDef(derived: TermSymbol, originalDef: DefDef, abstractOverClass: Boolean = true)(implicit ctx: Context): Tree =
polyDefDef(derived, trefs => vrefss => {
val origMeth = originalDef.symbol
val origClass = origMeth.enclosingClass.asClass
- val origTParams = allInstanceTypeParams(originalDef)
+ val origTParams = allInstanceTypeParams(originalDef, abstractOverClass)
val origVParams = originalDef.vparamss.flatten map (_.symbol)
val thisRef :: argRefs = vrefss.flatten
@@ -214,13 +218,13 @@ trait FullParameterization {
})
/** A forwarder expression which calls `derived`, passing along
- * - the type parameters and enclosing class parameters of `originalDef`,
+ * - if `abstractOverClass` the type parameters and enclosing class parameters of originalDef`,
* - the `this` of the enclosing class,
* - the value parameters of the original method `originalDef`.
*/
- def forwarder(derived: TermSymbol, originalDef: DefDef)(implicit ctx: Context): Tree =
+ def forwarder(derived: TermSymbol, originalDef: DefDef, abstractOverClass: Boolean = true)(implicit ctx: Context): Tree =
ref(derived.termRef)
- .appliedToTypes(allInstanceTypeParams(originalDef).map(_.typeRef))
+ .appliedToTypes(allInstanceTypeParams(originalDef, abstractOverClass).map(_.typeRef))
.appliedTo(This(originalDef.symbol.enclosingClass.asClass))
.appliedToArgss(originalDef.vparamss.nestedMap(vparam => ref(vparam.symbol)))
.withPos(originalDef.rhs.pos)
diff --git a/src/dotty/tools/dotc/transform/Getters.scala b/src/dotty/tools/dotc/transform/Getters.scala
index e018a45cc..918a92a04 100644
--- a/src/dotty/tools/dotc/transform/Getters.scala
+++ b/src/dotty/tools/dotc/transform/Getters.scala
@@ -58,7 +58,7 @@ class Getters extends MiniPhaseTransform with SymTransformer { thisTransform =>
}
else d
}
- private val NoGetterNeeded = Method | Param | JavaDefined | JavaStatic
+ private val NoGetterNeeded = Method | Param | JavaDefined | JavaStatic | Lazy
override def transformValDef(tree: ValDef)(implicit ctx: Context, info: TransformerInfo): Tree =
if (tree.symbol is Method) DefDef(tree.symbol.asTerm, tree.rhs) else tree
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/LazyVals.scala b/src/dotty/tools/dotc/transform/LazyVals.scala
index 7b6135dc0..dde086089 100644
--- a/src/dotty/tools/dotc/transform/LazyVals.scala
+++ b/src/dotty/tools/dotc/transform/LazyVals.scala
@@ -12,23 +12,34 @@ import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform
import dotty.tools.dotc.ast.Trees._
import dotty.tools.dotc.ast.{untpd, tpd}
import dotty.tools.dotc.core.Constants.Constant
-import dotty.tools.dotc.core.Types.MethodType
+import dotty.tools.dotc.core.Types.{ExprType, NoType, MethodType}
import dotty.tools.dotc.core.Names.Name
-import dotty.runtime.LazyVals
+import dotty.runtime.{LazyVals => RLazyVals} // dotty deviation
import SymUtils._
import scala.collection.mutable.ListBuffer
import dotty.tools.dotc.core.Denotations.SingleDenotation
import dotty.tools.dotc.core.SymDenotations.SymDenotation
-import dotty.tools.dotc.core.DenotTransformers.{IdentityDenotTransformer, DenotTransformer}
+import dotty.tools.dotc.core.DenotTransformers.{SymTransformer, IdentityDenotTransformer, DenotTransformer}
-class LazyValsTransform extends MiniPhaseTransform with IdentityDenotTransformer {
+class LazyVals extends MiniPhaseTransform with SymTransformer {
import tpd._
- def transformer = new LazyValsTransform
+ def transformSym(d: SymDenotation)(implicit ctx: Context): SymDenotation = {
+ if(d is(Flags.Lazy, butNot = Flags.ModuleVal | Flags.Method)) {
+ // Method flag is set on lazy vals coming from Unpickler. They are already methods and shouldn't be transformed twice
+ d.copySymDenotation(
+ initFlags = d.flags | Flags.Method,
+ info = ExprType(d.info))
+ }
+ else d
+ }
+
+ def transformer = new LazyVals
- val containerFlags = Flags.Synthetic | Flags.Mutable
+ val containerFlags = Flags.Synthetic | Flags.Mutable | Flags.Lazy
+ val initFlags = Flags.Synthetic | Flags.Method
/** this map contains mutable state of transformation: OffsetDefs to be appended to companion object definitions,
* and number of bits currently used */
@@ -72,9 +83,9 @@ class LazyValsTransform extends MiniPhaseTransform with IdentityDenotTransformer
* dotty.runtime(eg dotty.runtime.LazyInt)
*/
def transformLocalValDef(x: ValDef)(implicit ctx: Context) = x match {
- case x@ValDef(name, tpt, rhs) =>
- val valueInitter = rhs
+ case x@ValDef(name, tpt, valueInitter) =>
val holderName = ctx.freshName(name.toString + StdNames.nme.LAZY_LOCAL).toTermName
+ val initName = ctx.freshName(name.toString + StdNames.nme.LAZY_LOCAL_INIT).toTermName
val tpe = x.tpe.widen
val holderType =
@@ -88,21 +99,35 @@ class LazyValsTransform extends MiniPhaseTransform with IdentityDenotTransformer
else if (tpe isRef defn.ShortClass) "LazyShort"
else "LazyRef"
+
val holderImpl = ctx.requiredClass("dotty.runtime." + holderType)
- val holderSymbol = ctx.newSymbol(x.symbol.owner, holderName, containerFlags, holderImpl.typeRef, coord = x.symbol.coord)
- val holderTree = ValDef(holderSymbol, New(holderImpl.typeRef, List(valueInitter.changeOwner(x.symbol, holderSymbol))))
+ val holderSymbol = ctx.newSymbol(x.symbol.owner, holderName, containerFlags, holderImpl.typeRef, coord = x.pos)
+ val initSymbol = ctx.newSymbol(x.symbol.owner, initName, initFlags, MethodType(Nil, tpe), coord = x.pos)
+ val result = ref(holderSymbol).select("value".toTermName)
+ val flag = ref(holderSymbol).select("initialized".toTermName)
+ val initer = valueInitter.changeOwner(x.symbol, initSymbol)
+ val initBody =
+ ref(holderSymbol).select(defn.Object_synchronized).appliedToType(tpe).appliedTo(
+ mkNonThreadSafeDef(result, flag, initer).ensureConforms(tpe))
+ val initTree = DefDef(initSymbol, initBody)
+ val holderTree = ValDef(holderSymbol, New(holderImpl.typeRef, List()))
val methodBody = {
- val prefix = ref(holderSymbol).select("value".toTermName)
- if (holderType != "LazyRef") prefix
- else prefix.select(defn.Any_asInstanceOf).appliedToType(tpe)
+ tpd.If(flag, EmptyTree, ref(initSymbol))
+ result.ensureConforms(tpe)
}
val methodTree = DefDef(x.symbol.asTerm, methodBody)
ctx.debuglog(s"found a lazy val ${x.show},\n rewrote with ${holderTree.show}")
- Thicket(holderTree, methodTree)
+ Thicket(holderTree, initTree, methodTree)
}
- /** Create non-threadsafe lazy accessor equivalent to such code
+
+ override def transformStats(trees: List[tpd.Tree])(implicit ctx: Context, info: TransformerInfo): List[tpd.Tree] = {
+ val (holders, stats) = trees.partition { _.symbol.flags == containerFlags}
+ holders:::stats
+ }
+
+ /** Create non-threadsafe lazy accessor equivalent to such code
* def methodSymbol() = {
* if (flag) target
* else {
@@ -113,13 +138,11 @@ class LazyValsTransform extends MiniPhaseTransform with IdentityDenotTransformer
* }
*/
- def mkNonThreadSafeDef(target: Symbol, flag: Symbol, rhs: Tree)(implicit ctx: Context) = {
- val cond = ref(flag)
- val exp = ref(target)
- val setFlag = Assign(cond, Literal(Constants.Constant(true)))
- val setTarget = Assign(exp, rhs)
- val init = Block(List(setFlag, setTarget), exp)
- If(cond, exp, init)
+ def mkNonThreadSafeDef(target: Tree, flag: Tree, rhs: Tree)(implicit ctx: Context) = {
+ val setFlag = Assign(flag, Literal(Constants.Constant(true)))
+ val setTarget = Assign(target, rhs)
+ val init = Block(List(setFlag, setTarget), target)
+ If(flag, target, init)
}
/** Create non-threadsafe lazy accessor for not-nullable types equivalent to such code
@@ -155,7 +178,7 @@ class LazyValsTransform extends MiniPhaseTransform with IdentityDenotTransformer
val flagName = ctx.freshName(name.toString + StdNames.nme.BITMAP_PREFIX).toTermName
val flagSymbol = ctx.newSymbol(x.symbol.owner, flagName, containerFlags, defn.BooleanType)
val flag = ValDef(flagSymbol, Literal(Constants.Constant(false)))
- val slowPath = DefDef(x.symbol.asTerm, mkNonThreadSafeDef(containerSymbol, flagSymbol, rhs))
+ val slowPath = DefDef(x.symbol.asTerm, mkNonThreadSafeDef(ref(containerSymbol), ref(flagSymbol), rhs))
Thicket(List(containerTree, flag, slowPath))
}
@@ -266,7 +289,7 @@ class LazyValsTransform extends MiniPhaseTransform with IdentityDenotTransformer
val thiz = This(claz)(ctx.fresh.setOwner(claz))
val companion = claz.companionModule
val helperModule = ctx.requiredModule("dotty.runtime.LazyVals")
- val getOffset = Select(ref(helperModule), LazyVals.Names.getOffset.toTermName)
+ val getOffset = Select(ref(helperModule), RLazyVals.Names.getOffset.toTermName)
var offsetSymbol: TermSymbol = null
var flag: Tree = EmptyTree
var ord = 0
@@ -274,7 +297,7 @@ class LazyValsTransform extends MiniPhaseTransform with IdentityDenotTransformer
// compute or create appropriate offsetSymol, bitmap and bits used by current ValDef
appendOffsetDefs.get(companion.name.moduleClassName) match {
case Some(info) =>
- val flagsPerLong = 64 / LazyVals.BITS_PER_LAZY_VAL
+ val flagsPerLong = 64 / RLazyVals.BITS_PER_LAZY_VAL
info.ord += 1
ord = info.ord % flagsPerLong
val id = info.ord / flagsPerLong
@@ -305,11 +328,11 @@ class LazyValsTransform extends MiniPhaseTransform with IdentityDenotTransformer
val containerTree = ValDef(containerSymbol, initValue(tpe))
val offset = Select(ref(companion), offsetSymbol.name)
- val getFlag = Select(ref(helperModule), LazyVals.Names.get.toTermName)
- val setFlag = Select(ref(helperModule), LazyVals.Names.setFlag.toTermName)
- val wait = Select(ref(helperModule), LazyVals.Names.wait4Notification.toTermName)
- val state = Select(ref(helperModule), LazyVals.Names.state.toTermName)
- val cas = Select(ref(helperModule), LazyVals.Names.cas.toTermName)
+ val getFlag = Select(ref(helperModule), RLazyVals.Names.get.toTermName)
+ val setFlag = Select(ref(helperModule), RLazyVals.Names.setFlag.toTermName)
+ val wait = Select(ref(helperModule), RLazyVals.Names.wait4Notification.toTermName)
+ val state = Select(ref(helperModule), RLazyVals.Names.state.toTermName)
+ val cas = Select(ref(helperModule), RLazyVals.Names.cas.toTermName)
val accessor = mkThreadSafeDef(x.symbol.asTerm, claz, ord, containerSymbol, rhs, tpe, offset, getFlag, state, cas, setFlag, wait)
if(flag eq EmptyTree)
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/transform/TailRec.scala b/src/dotty/tools/dotc/transform/TailRec.scala
index f4e95830d..b747636c7 100644
--- a/src/dotty/tools/dotc/transform/TailRec.scala
+++ b/src/dotty/tools/dotc/transform/TailRec.scala
@@ -74,23 +74,25 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
final val labelPrefix = "tailLabel"
final val labelFlags = Flags.Synthetic | Flags.Label
- private def mkLabel(method: Symbol)(implicit c: Context): TermSymbol = {
+ private def mkLabel(method: Symbol, abstractOverClass: Boolean)(implicit c: Context): TermSymbol = {
val name = c.freshName(labelPrefix)
- c.newSymbol(method, name.toTermName, labelFlags, fullyParameterizedType(method.info, method.enclosingClass.asClass))
+ c.newSymbol(method, name.toTermName, labelFlags, fullyParameterizedType(method.info, method.enclosingClass.asClass, abstractOverClass))
}
override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ val sym = tree.symbol
tree match {
case dd@DefDef(name, tparams, vparamss0, tpt, rhs0)
- if (dd.symbol.isEffectivelyFinal) && !((dd.symbol is Flags.Accessor) || (rhs0 eq EmptyTree) || (dd.symbol is Flags.Label)) =>
- val mandatory = dd.symbol.hasAnnotation(defn.TailrecAnnotationClass)
+ if (sym.isEffectivelyFinal) && !((sym is Flags.Accessor) || (rhs0 eq EmptyTree) || (sym is Flags.Label)) =>
+ val mandatory = sym.hasAnnotation(defn.TailrecAnnotationClass)
atGroupEnd { implicit ctx: Context =>
cpy.DefDef(dd)(rhs = {
- val origMeth = tree.symbol
- val label = mkLabel(dd.symbol)
+ val defIsTopLevel = sym.owner.isClass
+ val origMeth = sym
+ val label = mkLabel(sym, abstractOverClass = defIsTopLevel)
val owner = ctx.owner.enclosingClass.asClass
val thisTpe = owner.thisType.widen
@@ -101,7 +103,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
// and second one will actually apply,
// now this speculatively transforms tree and throws away result in many cases
val rhsSemiTransformed = {
- val transformer = new TailRecElimination(dd.symbol, owner, thisTpe, mandatory, label)
+ val transformer = new TailRecElimination(origMeth, owner, thisTpe, mandatory, label, abstractOverClass = defIsTopLevel)
val rhs = atGroupEnd(transformer.transform(rhs0)(_))
rewrote = transformer.rewrote
rhs
@@ -109,8 +111,8 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
if (rewrote) {
val dummyDefDef = cpy.DefDef(tree)(rhs = rhsSemiTransformed)
- val res = fullyParameterizedDef(label, dummyDefDef)
- val call = forwarder(label, dd)
+ val res = fullyParameterizedDef(label, dummyDefDef, abstractOverClass = defIsTopLevel)
+ val call = forwarder(label, dd, abstractOverClass = defIsTopLevel)
Block(List(res), call)
} else {
if (mandatory)
@@ -130,7 +132,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
}
- class TailRecElimination(method: Symbol, enclosingClass: Symbol, thisType: Type, isMandatory: Boolean, label: Symbol) extends tpd.TreeMap {
+ class TailRecElimination(method: Symbol, enclosingClass: Symbol, thisType: Type, isMandatory: Boolean, label: Symbol, abstractOverClass: Boolean) extends tpd.TreeMap {
import dotty.tools.dotc.ast.tpd._
@@ -179,9 +181,11 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
val targs = typeArguments.map(noTailTransform)
val argumentss = arguments.map(noTailTransforms)
- val receiverIsSame = enclosingClass.typeRef.widen =:= recv.tpe.widen
- val receiverIsSuper = (method.name eq sym) && enclosingClass.typeRef.widen <:< recv.tpe.widen
- val receiverIsThis = recv.tpe.widen =:= thisType
+ val recvWiden = recv.tpe.widenDealias
+
+ val receiverIsSame = enclosingClass.typeRef.widenDealias =:= recvWiden
+ val receiverIsSuper = (method.name eq sym) && enclosingClass.typeRef.widen <:< recvWiden
+ val receiverIsThis = recv.tpe =:= thisType
val isRecursiveCall = (method eq sym)
@@ -204,9 +208,13 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
c.debuglog("Rewriting tail recursive call: " + tree.pos)
rewrote = true
val reciever = noTailTransform(recv)
- val classTypeArgs = recv.tpe.baseTypeWithArgs(enclosingClass).argInfos
- val trz = classTypeArgs.map(x => ref(x.typeSymbol))
- val callTargs: List[tpd.Tree] = targs ::: trz
+
+ val callTargs: List[tpd.Tree] =
+ if(abstractOverClass) {
+ val classTypeArgs = recv.tpe.baseTypeWithArgs(enclosingClass).argInfos
+ targs ::: classTypeArgs.map(x => ref(x.typeSymbol))
+ } else targs
+
val method = Apply(if (callTargs.nonEmpty) TypeApply(Ident(label.termRef), callTargs) else Ident(label.termRef),
List(reciever))
diff --git a/src/dotty/tools/dotc/typer/ErrorReporting.scala b/src/dotty/tools/dotc/typer/ErrorReporting.scala
index 8e8cf58f9..2ed720f83 100644
--- a/src/dotty/tools/dotc/typer/ErrorReporting.scala
+++ b/src/dotty/tools/dotc/typer/ErrorReporting.scala
@@ -96,7 +96,7 @@ object ErrorReporting {
def patternConstrStr(tree: Tree): String = ???
def typeMismatch(tree: Tree, pt: Type, implicitFailure: SearchFailure = NoImplicitMatches): Tree = {
- errorTree(tree, typeMismatchStr(tree.tpe, pt) + implicitFailure.postscript)
+ errorTree(tree, typeMismatchStr(normalize(tree.tpe, pt), pt) + implicitFailure.postscript)
}
/** A subtype log explaining why `found` does not conform to `expected` */
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 5111f10bd..53968ae91 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -337,25 +337,29 @@ trait ImplicitRunInfo { self: RunInfo =>
/** The implicit scope of type `tp`
* @param isLifted Type `tp` is the result of a `liftToClasses` application
*/
- def iscope(tp: Type, isLifted: Boolean = false): OfTypeImplicits =
+ def iscope(tp: Type, isLifted: Boolean = false): OfTypeImplicits = {
+ def computeIScope(cacheResult: Boolean) = {
+ val savedEphemeral = ctx.typerState.ephemeral
+ ctx.typerState.ephemeral = false
+ try {
+ val liftedTp = if (isLifted) tp else liftToClasses(tp)
+ val result =
+ if (liftedTp ne tp) iscope(liftedTp, isLifted = true)
+ else ofTypeImplicits(collectCompanions(tp))
+ if (ctx.typerState.ephemeral) record("ephemeral cache miss: implicitScope")
+ else if(cacheResult) implicitScopeCache(tp) = result
+ result
+ }
+ finally ctx.typerState.ephemeral |= savedEphemeral
+ }
+
if (tp.hash == NotCached || !Config.cacheImplicitScopes)
- ofTypeImplicits(collectCompanions(tp))
+ computeIScope(cacheResult = false)
else implicitScopeCache get tp match {
case Some(is) => is
- case None =>
- val savedEphemeral = ctx.typerState.ephemeral
- ctx.typerState.ephemeral = false
- try {
- val liftedTp = if (isLifted) tp else liftToClasses(tp)
- val result =
- if (liftedTp ne tp) iscope(liftedTp, isLifted = true)
- else ofTypeImplicits(collectCompanions(tp))
- if (ctx.typerState.ephemeral) record("ephemeral cache miss: implicitScope")
- else implicitScopeCache(tp) = result
- result
- }
- finally ctx.typerState.ephemeral |= savedEphemeral
- }
+ case None => computeIScope(cacheResult = true)
+ }
+ }
iscope(tp)
}
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index e41b2d194..38c1e49c5 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -99,6 +99,7 @@ trait Inferencing { this: Checking =>
/** Recursively widen and also follow type declarations and type aliases. */
def widenForMatchSelector(tp: Type)(implicit ctx: Context): Type = tp.widen match {
case tp: TypeRef if !tp.symbol.isClass => widenForMatchSelector(tp.info.bounds.hi)
+ case tp: AnnotatedType => tp.derivedAnnotatedType(tp.annot, widenForMatchSelector(tp.tpe))
case tp => tp
}
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 323a1100b..854af688a 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
@@ -656,6 +656,7 @@ class Namer { typer: Typer =>
(paramSymss :\ restpe1) { (params, restpe) =>
val make =
if (params.nonEmpty && (params.head is Implicit)) ImplicitMethodType
+ else if (ddef.mods.is(JavaDefined)) JavaMethodType
else MethodType
make.fromSymbols(params, restpe)
}
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 46aa2e953..f4b0ef4f2 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -43,7 +43,7 @@ trait TypeAssigner {
}
def apply(tp: Type) = tp match {
case tp: TermRef if toAvoid(tp) && variance > 0 =>
- apply(tp.info)
+ apply(tp.info.widenExpr)
case tp: TypeRef if (forbidden contains tp.symbol) || toAvoid(tp.prefix) =>
tp.info match {
case TypeAlias(ref) =>
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 9958b3b64..ce07ba74c 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)
}