summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala23
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala7
-rw-r--r--test/files/neg/null-unsoundness.check5
-rw-r--r--test/files/neg/null-unsoundness.scala15
4 files changed, 14 insertions, 36 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index f50f82d5b1..a63a717d2a 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -1159,10 +1159,12 @@ trait Types {
decls))
else super.normalize
- override def isVolatile =
+ override def isVolatile = false // for now; this should really be:
+ /*
!parents.isEmpty &&
(!parents.tail.isEmpty || !decls.isEmpty) &&
(parents exists (_.typeSymbol.isAbstractType))
+*/
override def kind = "RefinedType"
}
@@ -2588,6 +2590,12 @@ A type's typeSymbol should never be inspected directly.
}
}
+ def singletonBounds(hi: Type) = {
+ if (hi.isVolatile)
+ throw new MalformedType("cannot abstract over singleton with volatile type "+hi)
+ mkTypeBounds(NothingClass.tpe, intersectionType(List(hi, SingletonClass.tpe)))
+ }
+
/** A map to compute the asSeenFrom method */
class AsSeenFromMap(pre: Type, clazz: Symbol) extends TypeMap {
override val dropNonConstraintAnnotations = true
@@ -2628,8 +2636,7 @@ A type's typeSymbol should never be inspected directly.
def stabilize(pre: Type, clazz: Symbol): Type = {
capturedPre get clazz match {
case None =>
- val qvar = makeFreshExistential(".type", clazz,
- mkTypeBounds(NothingClass.tpe, intersectionType(List(pre, SingletonClass.tpe))))
+ val qvar = makeFreshExistential(".type", clazz, singletonBounds(pre))
capturedPre += (clazz -> qvar)
capturedParams = qvar :: capturedParams
qvar
@@ -2904,11 +2911,6 @@ A type's typeSymbol should never be inspected directly.
private var existSyms = immutable.Map.empty[Int, Symbol]
def existentialsNeeded: List[Symbol] = existSyms.values.toList
- private def boundFor(actualIdx: Int) =
- mkTypeBounds(
- NothingClass.tpe,
- intersectionType(List(actuals(actualIdx), SingletonClass.tpe)))
-
/* Return the type symbol for referencing a parameter index
* inside the existential quantifier. */
def existSymFor(actualIdx: Int, oldSym: Symbol) =
@@ -2916,11 +2918,10 @@ A type's typeSymbol should never be inspected directly.
existSyms(actualIdx)
else {
val symowner = oldSym.owner // what should be used??
- val bound = boundFor(actualIdx)
+ val bound = singletonBounds(actuals(actualIdx))
val sym =
- symowner.newAbstractType(
- oldSym.pos, oldSym.name+".type")
+ symowner.newAbstractType(oldSym.pos, oldSym.name+".type")
sym.setInfo(bound)
sym.setFlag(oldSym.flags)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 406e056128..ea7f9d447d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3290,11 +3290,8 @@ trait Typers { self: Analyzer =>
tree setType ref1.tpe.resultType
case SelectFromTypeTree(qual, selector) =>
-/* maybe need to do this:
- val res = typedSelect(typedType(qual, mode), selector)
- tree setType res.tpe setSymbol res.symbol
- res
-*/
+ val qual1 = typedType(qual, mode)
+ if (qual1.tpe.isVolatile) error(tree.pos, "illegal type selection from volatile type "+qual.tpe)
typedSelect(typedType(qual, mode), selector)
case CompoundTypeTree(templ) =>
diff --git a/test/files/neg/null-unsoundness.check b/test/files/neg/null-unsoundness.check
deleted file mode 100644
index 5f28e76d06..0000000000
--- a/test/files/neg/null-unsoundness.check
+++ /dev/null
@@ -1,5 +0,0 @@
-null-unsoundness.scala:8: error: stable identifier required, but A.this.x found.
- Note that value x is not stable because its type, A.this.D with A.this.A, is volatile.
- var y: x.T = new C("abc")
- ^
-one error found
diff --git a/test/files/neg/null-unsoundness.scala b/test/files/neg/null-unsoundness.scala
deleted file mode 100644
index d30ff613b1..0000000000
--- a/test/files/neg/null-unsoundness.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-class B
-class C(x: String) extends B
-
-class A {
- type A >: Null
- class D { type T >: C <: B }
- val x: D with A = null
- var y: x.T = new C("abc")
-}
-object Test extends A with Application {
- class C { type T = Int; val x = 1 }
- type A = C
- y = 42
-}
-