diff options
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 15 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 17 | ||||
-rw-r--r-- | test/dotc/tests.scala | 1 | ||||
-rw-r--r-- | tests/neg/i0248-inherit-refined.scala | 9 |
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 +} |