aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-03-19 10:33:55 +0100
committerTobias Schlatter <tobias@meisch.ch>2014-03-21 11:28:30 +0100
commit7e51434b89659c49a1cd755c224cc5ca270b82b3 (patch)
tree5cc0aa0c4d7005c720fda5238cffc2bcd760e3d6
parentc854cc7fcc9d0f889c6235c1534133cff7360e7f (diff)
downloaddotty-7e51434b89659c49a1cd755c224cc5ca270b82b3.tar.gz
dotty-7e51434b89659c49a1cd755c224cc5ca270b82b3.tar.bz2
dotty-7e51434b89659c49a1cd755c224cc5ca270b82b3.zip
Fix for t1292 - legal prefixes
The original test is now in error because the type Meta in the prefix Meta#Event is not stable and contains an abstract member Slog. Even after removing Slog, the test in pos was still in error because the bound type parameters were incorrectly recognized as abstract members. This has been fixed by the changes to Types.
-rw-r--r--src/dotty/tools/dotc/core/Types.scala24
-rw-r--r--test/dotc/tests.scala1
-rw-r--r--tests/neg/t1292.scala35
-rw-r--r--tests/pos/t1292.scala (renamed from tests/pending/pos/t1292.scala)5
4 files changed, 60 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index b6b17534e..967421f2b 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -121,7 +121,11 @@ object Types {
* !!! Todo: What about non-final vals that contain abstract types?
*/
final def isLegalPrefix(implicit ctx: Context): Boolean =
- isStable || memberNames(abstractTypeNameFilter).isEmpty
+ isStable || {
+ val absTypeNames = memberNames(abstractTypeNameFilter)
+ if (absTypeNames.nonEmpty) typr.println(s"abstract type members of ${this.showWithUnderlying}: $absTypeNames")
+ absTypeNames.isEmpty
+ }
/** Is this type guaranteed not to have `null` as a value?
* For the moment this is only true for modules, but it could
@@ -811,6 +815,14 @@ object Types {
/** Convert to text */
def toText(printer: Printer): Text = printer.toText(this)
+ /** Utility method to show the underlying type of a TypeProxy together
+ * with the proxy type itself.
+ */
+ def showWithUnderlying(implicit ctx: Context): String = this match {
+ case tp: TypeProxy => s"$show with underlying ${tp.underlying.show}"
+ case _ => show
+ }
+
type VarianceMap = SimpleMap[TypeVar, Integer]
/** All occurrences of type vars in this type that satisfy predicate
@@ -2407,7 +2419,15 @@ object Types {
/** A filter for names of abstract types of a given type */
object abstractTypeNameFilter extends NameFilter {
def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean =
- name.isTypeName && ((pre member name).symbol is Deferred)
+ name.isTypeName && {
+ val mbr = pre.member(name)
+ (mbr.symbol is Deferred) && {
+ mbr.info match {
+ case TypeBounds(lo, hi) => lo ne hi
+ case _ => false
+ }
+ }
+ }
}
/** A filter for names of deferred term definitions of a given type */
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index ee05dd15c..4b52b93c2 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -63,6 +63,7 @@ class tests extends CompilerTest {
@Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", "-language:noAutoTupling" :: Nil, xerrors = 3)
@Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 3)
@Test def neg_t0654_polyalias = compileFile(negDir, "t0654", xerrors = 2)
+ @Test def neg_t1192_legalPrefix = compileFile(negDir, "t1192", xerrors = 1)
@Test def dotc = compileDir(dotcDir + "tools/dotc", twice)
@Test def dotc_ast = compileDir(dotcDir + "tools/dotc/ast", twice)
diff --git a/tests/neg/t1292.scala b/tests/neg/t1292.scala
new file mode 100644
index 000000000..69e680320
--- /dev/null
+++ b/tests/neg/t1292.scala
@@ -0,0 +1,35 @@
+trait Foo[T <: Foo[T, Enum], Enum <: Enumeration] {
+ type StV = Enum#Value
+ type Meta = MegaFoo[T, Enum]
+
+ type Slog <: Enumeration
+
+ def getSingleton: Meta
+}
+
+trait MegaFoo[T <: Foo[T, Enum], Enum <: Enumeration] extends Foo[T, Enum] {
+ def doSomething(what: T, misc: StV, dog: Meta#Event) = None
+ // error: Meta is not a valid prefix for '#'.
+ // The error is correct. Meta is not stable, and it has an abstract type member Slog
+ abstract class Event
+ object Event
+
+ def stateEnumeration: Slog
+ def se2: Enum
+}
+
+object E extends Enumeration {
+ val A = Value
+ val B = Value
+}
+
+class RFoo extends Foo[RFoo, E.type] {
+ def getSingleton = MegaRFoo
+
+ type Slog = E.type
+}
+
+object MegaRFoo extends RFoo with MegaFoo[RFoo, E.type] {
+ def stateEnumeration = E
+ def se2 = E
+}
diff --git a/tests/pending/pos/t1292.scala b/tests/pos/t1292.scala
index 83a996d53..8e69734e9 100644
--- a/tests/pending/pos/t1292.scala
+++ b/tests/pos/t1292.scala
@@ -2,13 +2,14 @@ trait Foo[T <: Foo[T, Enum], Enum <: Enumeration] {
type StV = Enum#Value
type Meta = MegaFoo[T, Enum]
- type Slog <: Enumeration
+ type Slog = Enumeration
def getSingleton: Meta
}
trait MegaFoo[T <: Foo[T, Enum], Enum <: Enumeration] extends Foo[T, Enum] {
def doSomething(what: T, misc: StV, dog: Meta#Event) = None
+
abstract class Event
object Event
@@ -23,8 +24,6 @@ object E extends Enumeration {
class RFoo extends Foo[RFoo, E.type] {
def getSingleton = MegaRFoo
-
- type Slog = E.type
}
object MegaRFoo extends RFoo with MegaFoo[RFoo, E.type] {