aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-05-24 13:50:32 +0200
committerMartin Odersky <odersky@gmail.com>2015-06-06 11:04:53 +0200
commit3352ffc97f3577fd6de5c22a22c7c7c887e9b1f9 (patch)
treec2b31cca0fe9f6f05769c2dd6298f0d20c403257 /src
parentc8a479255745d7de391f386bbf8946233ff46f7d (diff)
downloaddotty-3352ffc97f3577fd6de5c22a22c7c7c887e9b1f9.tar.gz
dotty-3352ffc97f3577fd6de5c22a22c7c7c887e9b1f9.tar.bz2
dotty-3352ffc97f3577fd6de5c22a22c7c7c887e9b1f9.zip
Tighten isStable predicate
A term ref is stable only if its prefix is also stable. At the same time, we drop stability requirements where they no longer make sense (e.g. in isLegalPrefix).
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala14
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala7
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala8
3 files changed, 4 insertions, 25 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index ae9088f00..8825f396d 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -90,7 +90,7 @@ object Types {
/** Does this type denote a stable reference (i.e. singleton type)? */
final def isStable(implicit ctx: Context): Boolean = this match {
- case tp: TermRef => tp.termSymbol.isStable
+ case tp: TermRef => tp.termSymbol.isStable && tp.prefix.isStable
case _: SingletonType => true
case NoPrefix => true
case _ => false
@@ -154,18 +154,6 @@ object Types {
false
}
- /** A type T is a legal prefix in a type selection T#A if
- * T is stable or T contains no abstract types except possibly A.
- * !!! Todo: What about non-final vals that contain abstract types?
- */
- final def isLegalPrefixFor(selector: Name)(implicit ctx: Context): Boolean =
- isStable || {
- val absTypeNames = memberNames(abstractTypeNameFilter)
- if (absTypeNames.nonEmpty) typr.println(s"abstract type members of ${this.showWithUnderlying()}: $absTypeNames")
- absTypeNames.isEmpty ||
- absTypeNames.head == selector && absTypeNames.tail.isEmpty
- }
-
/** Is this type guaranteed not to have `null` as a value?
* For the moment this is only true for modules, but it could
* be refined later.
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index b2d368e8c..3ef6d059a 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -252,12 +252,6 @@ trait Checking {
if (!tp.isStable && !tp.isErroneous)
ctx.error(d"$tp is not stable", pos)
- /** Check that type `tp` is a legal prefix for '#'.
- * @return The type itself
- */
- def checkLegalPrefix(tp: Type, selector: Name, pos: Position)(implicit ctx: Context): Unit =
- if (!tp.isLegalPrefixFor(selector)) ctx.error(d"$tp is not a valid prefix for '# $selector'", pos)
-
/** Check that `tp` is a class type with a stable prefix. Also, if `traitReq` is
* true check that `tp` is a trait.
* Stability checking is disabled in phases after RefChecks.
@@ -345,7 +339,6 @@ trait NoChecking extends Checking {
override def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = tree
override def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit = ()
override def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = ()
- override def checkLegalPrefix(tp: Type, selector: Name, pos: Position)(implicit ctx: Context): Unit = ()
override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp
override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = ()
override def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index acf4f3845..fd1d034fd 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -312,13 +312,12 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (ctx.compilationUnit.isJava && tree.name.isTypeName) {
// SI-3120 Java uses the same syntax, A.B, to express selection from the
// value A and from the type A. We have to try both.
- tryEither(tryCtx => asSelect(tryCtx))((_,_) => asJavaSelectFromTypeTree(ctx))
+ tryEither(tryCtx => asSelect(tryCtx))((_, _) => asJavaSelectFromTypeTree(ctx))
} else asSelect(ctx)
}
def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): Tree = track("typedSelectFromTypeTree") {
val qual1 = typedType(tree.qualifier, selectionProto(tree.name, pt, this))
- checkLegalPrefix(qual1.tpe, tree.name, qual1.pos)
assignType(cpy.SelectFromTypeTree(tree)(qual1, tree.name), qual1)
}
@@ -347,8 +346,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val clsDef = TypeDef(x, templ).withFlags(Final)
typed(cpy.Block(tree)(clsDef :: Nil, New(Ident(x), Nil)), pt)
case _ =>
- val tpt1 = typedType(tree.tpt)
- checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos, traitReq = false)
+ val tpt1 = typedType(tree.tpt)
+ checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos, traitReq = false)
assignType(cpy.New(tree)(tpt1), tpt1)
// todo in a later phase: checkInstantiatable(cls, tpt1.pos)
}
@@ -524,7 +523,6 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
*/
var fnBody = tree.body
-
/** If function is of the form
* (x1, ..., xN) => f(x1, ..., XN)
* the type of `f`, otherwise NoType. (updates `fnBody` as a side effect).