Skip to content

Commit 7e51434

Browse files
oderskygzm0
authored andcommitted
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.
1 parent c854cc7 commit 7e51434

File tree

4 files changed

+60
-5
lines changed

4 files changed

+60
-5
lines changed

src/dotty/tools/dotc/core/Types.scala

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,11 @@ object Types {
121121
* !!! Todo: What about non-final vals that contain abstract types?
122122
*/
123123
final def isLegalPrefix(implicit ctx: Context): Boolean =
124-
isStable || memberNames(abstractTypeNameFilter).isEmpty
124+
isStable || {
125+
val absTypeNames = memberNames(abstractTypeNameFilter)
126+
if (absTypeNames.nonEmpty) typr.println(s"abstract type members of ${this.showWithUnderlying}: $absTypeNames")
127+
absTypeNames.isEmpty
128+
}
125129

126130
/** Is this type guaranteed not to have `null` as a value?
127131
* For the moment this is only true for modules, but it could
@@ -811,6 +815,14 @@ object Types {
811815
/** Convert to text */
812816
def toText(printer: Printer): Text = printer.toText(this)
813817

818+
/** Utility method to show the underlying type of a TypeProxy together
819+
* with the proxy type itself.
820+
*/
821+
def showWithUnderlying(implicit ctx: Context): String = this match {
822+
case tp: TypeProxy => s"$show with underlying ${tp.underlying.show}"
823+
case _ => show
824+
}
825+
814826
type VarianceMap = SimpleMap[TypeVar, Integer]
815827

816828
/** All occurrences of type vars in this type that satisfy predicate
@@ -2407,7 +2419,15 @@ object Types {
24072419
/** A filter for names of abstract types of a given type */
24082420
object abstractTypeNameFilter extends NameFilter {
24092421
def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean =
2410-
name.isTypeName && ((pre member name).symbol is Deferred)
2422+
name.isTypeName && {
2423+
val mbr = pre.member(name)
2424+
(mbr.symbol is Deferred) && {
2425+
mbr.info match {
2426+
case TypeBounds(lo, hi) => lo ne hi
2427+
case _ => false
2428+
}
2429+
}
2430+
}
24112431
}
24122432

24132433
/** A filter for names of deferred term definitions of a given type */

test/dotc/tests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class tests extends CompilerTest {
6363
@Test def neg_autoTupling = compileFile(posDir, "autoTuplingTest", "-language:noAutoTupling" :: Nil, xerrors = 3)
6464
@Test def neg_autoTupling2 = compileFile(negDir, "autoTuplingTest", xerrors = 3)
6565
@Test def neg_t0654_polyalias = compileFile(negDir, "t0654", xerrors = 2)
66+
@Test def neg_t1192_legalPrefix = compileFile(negDir, "t1192", xerrors = 1)
6667

6768
@Test def dotc = compileDir(dotcDir + "tools/dotc", twice)
6869
@Test def dotc_ast = compileDir(dotcDir + "tools/dotc/ast", twice)

tests/neg/t1292.scala

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
trait Foo[T <: Foo[T, Enum], Enum <: Enumeration] {
2+
type StV = Enum#Value
3+
type Meta = MegaFoo[T, Enum]
4+
5+
type Slog <: Enumeration
6+
7+
def getSingleton: Meta
8+
}
9+
10+
trait MegaFoo[T <: Foo[T, Enum], Enum <: Enumeration] extends Foo[T, Enum] {
11+
def doSomething(what: T, misc: StV, dog: Meta#Event) = None
12+
// error: Meta is not a valid prefix for '#'.
13+
// The error is correct. Meta is not stable, and it has an abstract type member Slog
14+
abstract class Event
15+
object Event
16+
17+
def stateEnumeration: Slog
18+
def se2: Enum
19+
}
20+
21+
object E extends Enumeration {
22+
val A = Value
23+
val B = Value
24+
}
25+
26+
class RFoo extends Foo[RFoo, E.type] {
27+
def getSingleton = MegaRFoo
28+
29+
type Slog = E.type
30+
}
31+
32+
object MegaRFoo extends RFoo with MegaFoo[RFoo, E.type] {
33+
def stateEnumeration = E
34+
def se2 = E
35+
}

tests/pending/pos/t1292.scala renamed to tests/pos/t1292.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ trait Foo[T <: Foo[T, Enum], Enum <: Enumeration] {
22
type StV = Enum#Value
33
type Meta = MegaFoo[T, Enum]
44

5-
type Slog <: Enumeration
5+
type Slog = Enumeration
66

77
def getSingleton: Meta
88
}
99

1010
trait MegaFoo[T <: Foo[T, Enum], Enum <: Enumeration] extends Foo[T, Enum] {
1111
def doSomething(what: T, misc: StV, dog: Meta#Event) = None
12+
1213
abstract class Event
1314
object Event
1415

@@ -23,8 +24,6 @@ object E extends Enumeration {
2324

2425
class RFoo extends Foo[RFoo, E.type] {
2526
def getSingleton = MegaRFoo
26-
27-
type Slog = E.type
2827
}
2928

3029
object MegaRFoo extends RFoo with MegaFoo[RFoo, E.type] {

0 commit comments

Comments
 (0)