aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala9
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala2
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala2
-rw-r--r--src/dotty/tools/dotc/core/Scopes.scala2
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala14
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala4
-rw-r--r--src/dotty/tools/dotc/core/Types.scala62
-rw-r--r--src/dotty/tools/dotc/printing/PlainPrinter.scala14
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala13
-rw-r--r--src/dotty/tools/dotc/typer/ImportInfo.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala5
-rw-r--r--test/test/ShowClassTests.scala4
-rw-r--r--test/test/showClass.scala2
-rw-r--r--tests/pos/functions1.scala21
15 files changed, 125 insertions, 33 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index a04b7b2da..e52ff9d62 100644
--- a/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -248,6 +248,15 @@ trait TreeInfo[T >: Untyped] { self: Trees.Instance[T] =>
/** Is this case guarded? */
def isGuardedCase(cdef: CaseDef) = cdef.guard ne EmptyTree
+ /** True iff definition if a val or def with no right-hand-side, or it
+ * is an abstract typoe declaration
+ */
+ def lacksDefinition(mdef: MemberDef) = mdef match {
+ case mdef: ValOrDefDef => mdef.rhs.isEmpty && !mdef.name.isConstructorName
+ case mdef: TypeDef => mdef.rhs.isEmpty || mdef.rhs.isInstanceOf[TypeBoundsTree]
+ case _ => false
+ }
+
/** The underlying pattern ignoring any bindings */
def unbind(x: Tree): Tree = unsplice(x) match {
case Bind(_, y) => unbind(y)
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index bf3b3633b..b66b4d017 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -293,7 +293,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
} // no checks necessary
def ref(sym: Symbol)(implicit ctx: Context): tpd.NameTree =
- ref(NamedType(sym.owner.thisType, sym.name).withDenot(sym))
+ ref(NamedType(sym.owner.thisType, sym.name, sym.denot))
// ----- Converting to releated trees -----------------------------------------------
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala
index 6930429b5..562974c48 100644
--- a/src/dotty/tools/dotc/core/Annotations.scala
+++ b/src/dotty/tools/dotc/core/Annotations.scala
@@ -55,7 +55,7 @@ object Annotations {
deferred(atp.classSymbol, New(atp, args))
def makeAlias(sym: TermSymbol)(implicit ctx: Context) =
- apply(defn.AliasAnnot, List(Ident(TermRef.withSig(sym.owner.thisType, sym.name, sym.signature).withDenot(sym))))
+ apply(defn.AliasAnnot, List(Ident(TermRef.withSig(sym.owner.thisType, sym.name, sym.signature, sym))))
def makeChild(sym: Symbol)(implicit ctx: Context) =
apply(defn.ChildAnnot.typeRef.appliedTo(sym.owner.thisType.select(sym.name, sym)), Nil)
diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala
index 46cbee99d..b1b81c4a9 100644
--- a/src/dotty/tools/dotc/core/Scopes.scala
+++ b/src/dotty/tools/dotc/core/Scopes.scala
@@ -294,7 +294,7 @@ object Scopes {
while (e ne null) {
if (e.sym is Implicit) {
val d = e.sym.denot
- irefs += TermRef.withSig(NoPrefix, e.sym.asTerm.name, d.signature).withDenot(e.sym.denot)
+ irefs += TermRef.withSig(NoPrefix, e.sym.asTerm.name, d.signature, e.sym.denot)
}
e = e.prev
}
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 3c6a32707..ccf4f83e7 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -117,6 +117,12 @@ object SymDenotations {
case _ => myInfo
}
+ /** Optionally, the info if it is completed */
+ final def unforcedInfo: Option[Type] = myInfo match {
+ case myInfo: LazyType => None
+ case _ => Some(myInfo)
+ }
+
private def completeFrom(completer: LazyType): Unit = {
if (myFlags is Touched) throw new CyclicReference(this)
myFlags |= Touched
@@ -646,17 +652,17 @@ object SymDenotations {
/** The TypeRef representing this type denotation at its original location. */
def typeRef(implicit ctx: Context): TypeRef =
- TypeRef(owner.thisType, name.asTypeName).withDenot(this)
+ TypeRef(owner.thisType, name.asTypeName, this)
/** The TermRef representing this term denotation at its original location. */
def termRef(implicit ctx: Context): TermRef =
- TermRef(owner.thisType, name.asTermName).withDenot(this)
+ TermRef(owner.thisType, name.asTermName, this)
/** The TermRef representing this term denotation at its original location
* and at signature `NotAMethod`.
*/
def valRef(implicit ctx: Context): TermRef =
- TermRef.withSig(owner.thisType, name.asTermName, Signature.NotAMethod).withDenot(this)
+ TermRef.withSig(owner.thisType, name.asTermName, Signature.NotAMethod, this)
/** The TermRef representing this term denotation at its original location
* at the denotation's signature.
@@ -664,7 +670,7 @@ object SymDenotations {
* denotation via a call to `info`.
*/
def termRefWithSig(implicit ctx: Context): TermRef =
- TermRef.withSig(owner.thisType, name.asTermName, signature).withDenot(this)
+ TermRef.withSig(owner.thisType, name.asTermName, signature, this)
/** The NamedType representing this denotation at its original location.
* Same as either `typeRef` or `termRefWithSig` depending whether this denotes a type or not.
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index fd661aab1..599e4b0f0 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -129,8 +129,8 @@ class TypeApplications(val self: Type) extends AnyVal {
*/
final def toBounds(tparam: Symbol)(implicit ctx: Context): TypeBounds = {
val v = tparam.variance
- if (v > 0 && !(tparam is Local)) TypeBounds.upper(self)
- else if (v < 0 && !(tparam is Local)) TypeBounds.lower(self)
+ if (v > 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.upper(self)
+ else if (v < 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.lower(self)
else TypeAlias(self, v)
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 16a084b81..1b05594e6 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -629,10 +629,10 @@ object Types {
/** The type <this . name> , reduced if possible, with given denotation if unreduced */
def select(name: Name, denot: Denotation)(implicit ctx: Context): Type = name match {
case name: TermName =>
- TermRef(this, name).withDenot(denot)
+ TermRef(this, name, denot)
case name: TypeName =>
val res = lookupRefined(this, name)
- if (res.exists) res else TypeRef(this, name).withDenot(denot)
+ if (res.exists) res else TypeRef(this, name, denot)
}
/** The type <this . name> with given symbol, reduced if possible */
@@ -1162,7 +1162,7 @@ object Types {
def isOverloaded(implicit ctx: Context) = denot.isOverloaded
private def rewrap(sd: SingleDenotation)(implicit ctx: Context) =
- TermRef(prefix, name) withDenot sd
+ TermRef(prefix, name, sd)
def alternatives(implicit ctx: Context): List[TermRef] =
denot.alternatives map rewrap
@@ -1176,6 +1176,7 @@ object Types {
}
final class TermRefWithSignature(prefix: Type, name: TermName, val sig: Signature) extends TermRef(prefix, name) {
+ assert(prefix ne NoPrefix)
override def signature(implicit ctx: Context) = sig
override def loadDenot(implicit ctx: Context): Denotation =
super.loadDenot.atSignature(sig)
@@ -1192,29 +1193,59 @@ object Types {
override def computeHash = doHash((name, sig), prefix)
}
- final class CachedTermRef(prefix: Type, name: TermName) extends TermRef(prefix, name)
- final class CachedTypeRef(prefix: Type, name: TypeName) extends TypeRef(prefix, name)
+ trait WithNoPrefix extends NamedType {
+ def fixedSym: Symbol
+ assert(fixedSym ne NoSymbol)
+ withSym(fixedSym)
+ override def equals(that: Any) = that match {
+ case that: WithNoPrefix => this.fixedSym eq that.fixedSym
+ case _ => false
+ }
+ override def computeHash = doHash(fixedSym)
+ }
+
+ final class CachedTermRef(prefix: Type, name: TermName) extends TermRef(prefix, name) {
+ assert(prefix ne NoPrefix)
+ }
+ final class CachedTypeRef(prefix: Type, name: TypeName) extends TypeRef(prefix, name) {
+ assert(prefix ne NoPrefix)
+ }
+
+ final class NoPrefixTermRef(name: TermName, val fixedSym: TermSymbol) extends TermRef(NoPrefix, name) with WithNoPrefix
+ final class NoPrefixTypeRef(name: TypeName, val fixedSym: TypeSymbol) extends TypeRef(NoPrefix, name) with WithNoPrefix
object NamedType {
def apply(prefix: Type, name: Name)(implicit ctx: Context) =
if (name.isTermName) TermRef(prefix, name.asTermName)
else TypeRef(prefix, name.asTypeName)
+ def apply(prefix: Type, name: Name, denot: Denotation)(implicit ctx: Context) =
+ if (name.isTermName) TermRef(prefix, name.asTermName, denot)
+ else TypeRef(prefix, name.asTypeName, denot)
}
object TermRef {
def apply(prefix: Type, name: TermName)(implicit ctx: Context): TermRef =
unique(new CachedTermRef(prefix, name))
def apply(prefix: Type, sym: TermSymbol)(implicit ctx: Context): TermRef =
- apply(prefix, sym.name) withSym sym
+ if (prefix eq NoPrefix) unique(new NoPrefixTermRef(sym.name, sym))
+ else apply(prefix, sym.name) withSym sym
+ def apply(prefix: Type, name: TermName, denot: Denotation)(implicit ctx: Context): TermRef =
+ (if (prefix eq NoPrefix) apply(prefix, denot.symbol.asTerm) else apply(prefix, name)) withDenot denot
def withSig(prefix: Type, name: TermName, sig: Signature)(implicit ctx: Context): TermRef =
unique(new TermRefWithSignature(prefix, name, sig))
+ def withSig(prefix: Type, name: TermName, sig: Signature, denot: Denotation)(implicit ctx: Context): TermRef =
+ (if (prefix eq NoPrefix) apply(prefix, denot.symbol.asTerm)
+ else withSig(prefix, name, sig)) withDenot denot
}
object TypeRef {
def apply(prefix: Type, name: TypeName)(implicit ctx: Context): TypeRef =
unique(new CachedTypeRef(prefix, name))
def apply(prefix: Type, sym: TypeSymbol)(implicit ctx: Context): TypeRef =
- apply(prefix, sym.name) withSym sym
+ if (prefix eq NoPrefix) unique(new NoPrefixTypeRef(sym.name, sym))
+ else apply(prefix, sym.name) withSym sym
+ def apply(prefix: Type, name: TypeName, denot: Denotation)(implicit ctx: Context): TypeRef =
+ (if (prefix eq NoPrefix) apply(prefix, denot.symbol.asType) else apply(prefix, name)) withDenot denot
}
// --- Other SingletonTypes: ThisType/SuperType/ConstantType ---------------------------
@@ -1727,11 +1758,24 @@ object Types {
selfInfo: DotClass /* should be: Type | Symbol */) extends CachedGroundType with TypeType {
def selfType(implicit ctx: Context): Type = selfInfo match {
- case NoType => cls.typeRef
+ case NoType =>
+ if (selfTypeCache == null) selfTypeCache = computeSelfType(cls.typeRef, cls.typeParams)
+ selfTypeCache
case tp: Type => tp
case self: Symbol => self.info
}
+ private var selfTypeCache: Type = null
+
+ private def computeSelfType(base: Type, tparams: List[TypeSymbol])(implicit ctx: Context): Type = tparams match {
+ case tparam :: tparams1 =>
+ computeSelfType(
+ RefinedType(base, tparam.name, TypeRef(cls.thisType, tparam).toBounds(tparam)),
+ tparams1)
+ case nil =>
+ base
+ }
+
def rebase(tp: Type)(implicit ctx: Context): Type =
if ((prefix eq cls.owner.thisType) || !cls.owner.isClass) tp
else tp.substThis(cls.owner.asClass, prefix)
@@ -2189,7 +2233,7 @@ object Types {
case tp: NamedType if (p(tp)) =>
foldOver(x += tp, tp)
case tp: ThisType =>
- apply(x, tp.underlying)
+ apply(x, if (tp.cls is Module) tp.underlying else tp.cls.typeRef)
case _ =>
foldOver(x, tp)
}
diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 11a984ad3..791380852 100644
--- a/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -219,6 +219,14 @@ class PlainPrinter(_ctx: Context) extends Printer {
protected def isEmptyPrefix(sym: Symbol) =
sym.isEffectiveRoot || sym.isAnonymousClass || sym.name.isReplWrapperName
+ /** String representation of a definition's type following its name,
+ * if symbol is completed, "?" otherwise.
+ */
+ protected def toTextRHS(optType: Option[Type]): Text = optType match {
+ case Some(tp) => toTextRHS(tp)
+ case None => "?"
+ }
+
/** String representation of a definition's type following its name */
protected def toTextRHS(tp: Type): Text = controlled {
tp match {
@@ -295,14 +303,14 @@ class PlainPrinter(_ctx: Context) extends Printer {
else if (flags is Mutable) "var"
else if (flags is Package) "package"
else if (flags is Module) "object"
- else if (sym.isSourceMethod) "def"
+ else if (sym.isCompleted && sym.isSourceMethod) "def"
else if (sym.isTerm && (!(flags is Param))) "val"
else ""
}
/** String representation of symbol's flags */
protected def toTextFlags(sym: Symbol): Text =
- Text(sym.flags.flagStrings map stringToText, " ")
+ Text(sym.flagsUNSAFE.flagStrings map stringToText, " ")
/** String representation of symbol's variance or "" if not applicable */
protected def varianceString(sym: Symbol): String = sym.variance match {
@@ -313,7 +321,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
def dclText(sym: Symbol): Text =
(toTextFlags(sym) ~~ keyString(sym) ~~
- (varianceString(sym) ~ nameString(sym)) ~ toTextRHS(sym.info)).close
+ (varianceString(sym) ~ nameString(sym)) ~ toTextRHS(sym.unforcedInfo)).close
def toText(sym: Symbol): Text =
(kindString(sym) ~~ {
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 050b27587..9fc8cb513 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -431,7 +431,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
}
override def toTextFlags(sym: Symbol) = {
- var flags = sym.flags
+ var flags = sym.flagsUNSAFE
if (flags is TypeParam) flags = flags &~ Protected
Text(flags.flagStrings.filterNot(_.startsWith("<")) map stringToText, " ")
}
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 64f44ee5e..dba95c689 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -621,10 +621,13 @@ trait Applications extends Compatibility { self: Typer =>
}
println(i"case 2 $unapplyArgType ${ctx.typerState.constraint}")
unapplyArgType
- } else errorType(
- i"Pattern type $unapplyArgType is neither a subtype nor a supertype of selector type $wpt",
- tree.pos)
-
+ } else {
+ // println("Neither sub nor super")
+ // println(TypeComparer.explained(implicit ctx => unapplyArgType <:< wpt))
+ errorType(
+ i"Pattern type $unapplyArgType is neither a subtype nor a supertype of selector type $wpt",
+ tree.pos)
+ }
var argTypes = unapplyArgs(mt.resultType)
val bunchedArgs = argTypes match {
case argType :: Nil if argType.isRepeatedParam => untpd.SeqLiteral(args) :: Nil
@@ -666,7 +669,7 @@ trait Applications extends Compatibility { self: Typer =>
isApplicable(methRef, args, resultType)
case _ =>
val app = tp.member(nme.apply)
- app.exists && app.hasAltWith(d => isApplicable(TermRef(tp, nme.apply).withDenot(d), args, resultType))
+ app.exists && app.hasAltWith(d => isApplicable(TermRef(tp, nme.apply, d), args, resultType))
}
/** In a set of overloaded applicable alternatives, is `alt1` at least as good as
diff --git a/src/dotty/tools/dotc/typer/ImportInfo.scala b/src/dotty/tools/dotc/typer/ImportInfo.scala
index 9942e1915..d72e12baa 100644
--- a/src/dotty/tools/dotc/typer/ImportInfo.scala
+++ b/src/dotty/tools/dotc/typer/ImportInfo.scala
@@ -86,7 +86,7 @@ class ImportInfo(val sym: Symbol, val selectors: List[untpd.Tree], val isRootImp
for {
renamed <- reverseMapping.keys
denot <- pre.member(reverseMapping(renamed)).altsWith(_ is Implicit)
- } yield TermRef.withSig(pre, renamed, denot.signature).withDenot(denot)
+ } yield TermRef.withSig(pre, renamed, denot.signature, denot)
}
override def toString = {
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 99c036fe8..3ddd3980b 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -166,8 +166,9 @@ class Namer { typer: Typer =>
adjustIfModule(new Completer(tree) withDecls newScope, tree),
privateWithinClass(tree.mods), tree.pos, ctx.source.file))
case tree: MemberDef =>
+ val deferred = if (lacksDefinition(tree)) Deferred else EmptyFlags
record(ctx.newSymbol(
- ctx.owner, tree.name.encode, tree.mods.flags,
+ ctx.owner, tree.name.encode, tree.mods.flags | deferred,
adjustIfModule(new Completer(tree), tree),
privateWithinClass(tree.mods), tree.pos))
case tree: Import =>
@@ -408,6 +409,8 @@ class Namer { typer: Typer =>
tp & itpe
}
}
+ // println(s"final inherited for $sym: ${inherited.toString}") !!!
+ // println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}")
def rhsType = adapt(typedAheadExpr(mdef.rhs), WildcardType).tpe.widen
def lhsType = fullyDefinedType(rhsType, "right-hand side", mdef.pos)
inherited orElse lhsType
diff --git a/test/test/ShowClassTests.scala b/test/test/ShowClassTests.scala
index c0533e221..93d8213c6 100644
--- a/test/test/ShowClassTests.scala
+++ b/test/test/ShowClassTests.scala
@@ -122,12 +122,12 @@ class ShowClassTests extends DottyTest {
*/
@Test
def showScala() = {
- showPackage("scala", 22)
+ showPackage("scala", 1)
}
@Test
def loadDotty() = {
- showPackage("dotty", 23)
+ showPackage("dotty", 2)
}
diff --git a/test/test/showClass.scala b/test/test/showClass.scala
index 4824523dc..ee71854d1 100644
--- a/test/test/showClass.scala
+++ b/test/test/showClass.scala
@@ -13,6 +13,6 @@ object showClass extends ShowClassTests {
// showPackage("scala.collection")
showPackage("dotty", 1)
- showPackage("scala", 18)
+ showPackage("scala", 2)
}
}
diff --git a/tests/pos/functions1.scala b/tests/pos/functions1.scala
index 12df12e50..99709bc88 100644
--- a/tests/pos/functions1.scala
+++ b/tests/pos/functions1.scala
@@ -10,5 +10,24 @@ object Functions {
val xf2: String => Int = x.foo(_)
val x2: String => Int = x.foo
val x3 = x.foo _
-
+ /*
+ abstract class Spore[T, U] {
+ def run(x: T): U
+ }
+
+ trait Spore2[T, U] { self: Spore2[T, U] =>
+ def run(x: T): U
+ }
+
+ val x: String => String = {
+ case "abc" => ""
+ case x => x
+ }
+ val y: PartialFunction[String, String] = x => x match {
+ case "abc" => ""
+ case _ => x
+ }
+ val z: Spore[String, String] = x => x + x
+ val z2: Spore2[String, String] = x => x + x
+ */
}