diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index 343a97c66ada..59135bf21441 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -424,6 +424,9 @@ object Flags { /** A method that is known to have no default parameters */ final val NoDefaultParams = termFlag(61, "") + /** A type symbol with provisional empty bounds */ + final val Provisional = typeFlag(61, "") + /** A denotation that is valid in all run-ids */ final val Permanent = commonFlag(62, "") diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 416daeabee84..d14c90f5314e 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -3012,15 +3012,18 @@ object Types { override def superType(implicit ctx: Context): Type = { if (ctx.period != validSuper) { + validSuper = ctx.period cachedSuper = tycon match { case tp: HKTypeLambda => defn.AnyType case tp: TypeVar if !tp.inst.exists => // supertype not stable, since underlying might change - return tp.underlying.applyIfParameterized(args) - case tp: TypeProxy => tp.superType.applyIfParameterized(args) + validSuper = Nowhere + tp.underlying.applyIfParameterized(args) + case tp: TypeProxy => + if (tp.typeSymbol.is(Provisional)) validSuper = Nowhere + tp.superType.applyIfParameterized(args) case _ => defn.AnyType } - validSuper = ctx.period } cachedSuper } diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index f9addf9cc8a5..2e84a2389a9f 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1159,6 +1159,7 @@ class Namer { typer: Typer => def abstracted(tp: Type): Type = HKTypeLambda.fromParams(tparamSyms, tp) val dummyInfo = abstracted(TypeBounds.empty) sym.info = dummyInfo + sym.setFlag(Provisional) // Temporarily set info of defined type T to ` >: Nothing <: Any. // This is done to avoid cyclic reference errors for F-bounds. // This is subtle: `sym` has now an empty TypeBounds, but is not automatically diff --git a/tests/pos/i2888.scala b/tests/pos/i2888.scala new file mode 100644 index 000000000000..17f1118c5db4 --- /dev/null +++ b/tests/pos/i2888.scala @@ -0,0 +1,13 @@ +trait Foo[A, CC[X] <: Foo[X, CC, CC[X]], C <: CC[A]] { + + def cc: CC[A] + + def foo: Unit = () + + def bar: Unit = cc.foo + +} + +object Main { + def main(args: Array[String]): Unit = () +}