aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-12-14 17:32:16 +0100
committerMartin Odersky <odersky@gmail.com>2013-12-14 17:32:16 +0100
commit01db9a68e5e68f08c8236c23c905009789d51587 (patch)
tree3e45103b0d36505d6f86f3024e56780e840c156b /src/dotty/tools
parentd65587ae74cfe2dc7601f57e163b7e22bf89582a (diff)
downloaddotty-01db9a68e5e68f08c8236c23c905009789d51587.tar.gz
dotty-01db9a68e5e68f08c8236c23c905009789d51587.tar.bz2
dotty-01db9a68e5e68f08c8236c23c905009789d51587.zip
Fixed several deep problems in handling of types and symbols.
1. We forgot to mark declaration symbols Deferred. 2. Types with NoPrefix and the same name got identified. Fixed by adding a new category WithNoPrefix to named types, and changing the way named types get generated. 3. Self types lacked parameters. (Question: Do we need to also track type members?) 4. Printers caused cyclic reference errors. Now some print operations are more careful with forcing. 5. Namedparts accumulator has to be more careful with ThisTypes. Because self types now contain parameters, which might lead back to this, we only add the class name (or the source module, if it's a module class). 6. toBounds in TypeApplications needs to use Co/Contra aliases for expanded name parameters, not just local ones.
Diffstat (limited to 'src/dotty/tools')
-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
12 files changed, 102 insertions, 29 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