aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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] {