aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/Types.scala15
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala17
-rw-r--r--test/dotc/tests.scala1
-rw-r--r--tests/neg/i0248-inherit-refined.scala9
5 files changed, 30 insertions, 14 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 017b7cadc..987014ff4 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -700,15 +700,20 @@ object Types {
/** If this is a (possibly aliased, annotated, and/or parameterized) reference to
* a class, the class type ref, otherwise NoType.
+ * @param refinementOK If `true` we also skip non-parameter refinements.
*/
- def underlyingClassRef(implicit ctx: Context): Type = dealias match {
+ def underlyingClassRef(refinementOK: Boolean)(implicit ctx: Context): Type = dealias match {
case tp: TypeRef =>
if (tp.symbol.isClass) tp
- else if (tp.symbol.isAliasType) tp.underlying.underlyingClassRef
+ else if (tp.symbol.isAliasType) tp.underlying.underlyingClassRef(refinementOK)
else NoType
- case tp: TypeVar => tp.underlying.underlyingClassRef
- case tp: AnnotatedType => tp.underlying.underlyingClassRef
- case tp: RefinedType => tp.underlying.underlyingClassRef
+ case tp: AnnotatedType => tp.underlying.underlyingClassRef(refinementOK)
+ case tp: RefinedType =>
+ if (refinementOK) tp.underlying.underlyingClassRef(refinementOK)
+ else {
+ val tycon = tp.withoutArgs(tp.argInfos)
+ if (tycon eq tp) NoType else tycon.underlyingClassRef(refinementOK)
+ }
case _ => NoType
}
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 17cba1373..9e13ec13b 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -248,7 +248,7 @@ trait Checking {
* @return `tp` itself if it is a class or trait ref, ObjectClass.typeRef if not.
*/
def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type =
- tp.underlyingClassRef match {
+ tp.underlyingClassRef(refinementOK = false) match {
case tref: TypeRef =>
if (ctx.phase <= ctx.refchecksPhase) checkStable(tref.prefix, pos)
if (traitReq && !(tref.symbol is Trait)) ctx.error(d"$tref is not a trait", pos)
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index 9e34d549a..05be46f29 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -106,14 +106,15 @@ trait Inferencing { this: Checking =>
* class type reference where the class has a companion module, a reference to
* that companion module. Otherwise NoType
*/
- def companionRef(tp: Type)(implicit ctx: Context): Type = tp.underlyingClassRef match {
- case tp: TypeRef =>
- val companion = tp.classSymbol.companionModule
- if (companion.exists)
- companion.valRef.asSeenFrom(tp.prefix, companion.symbol.owner)
- else NoType
- case _ => NoType
- }
+ def companionRef(tp: Type)(implicit ctx: Context): Type =
+ tp.underlyingClassRef(refinementOK = true) match {
+ case tp: TypeRef =>
+ val companion = tp.classSymbol.companionModule
+ if (companion.exists)
+ companion.valRef.asSeenFrom(tp.prefix, companion.symbol.owner)
+ else NoType
+ case _ => NoType
+ }
/** Ensure that the first type in a list of parent types Ps points to a non-trait class.
* If that's not already the case, add one. The added class type CT is determined as follows.
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index 9e1d26c55..3ecf8e10e 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -107,6 +107,7 @@ class tests extends CompilerTest {
@Test def neg_cycles = compileFile(negDir, "cycles", xerrors = 8)
@Test def neg_boundspropagation = compileFile(negDir, "boundspropagation", xerrors = 4)
@Test def neg_refinedSubtyping = compileFile(negDir, "refinedSubtyping", xerrors = 2)
+ @Test def neg_i0248_inherit_refined = compileFile(negDir, "i0248-inherit-refined", xerrors = 3)
@Test def dotc = compileDir(dotcDir + "tools/dotc", twice)(allowDeepSubtypes)
@Test def dotc_ast = compileDir(dotcDir + "tools/dotc/ast", twice)
diff --git a/tests/neg/i0248-inherit-refined.scala b/tests/neg/i0248-inherit-refined.scala
new file mode 100644
index 000000000..246d8163e
--- /dev/null
+++ b/tests/neg/i0248-inherit-refined.scala
@@ -0,0 +1,9 @@
+object test {
+ class A { type T }
+ type X = A { type T = Int }
+ class B extends X
+ type Y = A & B
+ class C extends Y
+ type Z = A | B
+ class D extends Z
+}