diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 4ba902218ee5..1ceb4d5428ab 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -2078,7 +2078,7 @@ class TypeComparer(using val comparerCtx: Context) extends ConstraintHandling wi * * [X1, ..., Xn] -> op(tp1[X1, ..., Xn], tp2[X1, ..., Xn]) */ - private def liftIfHK(tp1: Type, tp2: Type, + def liftIfHK(tp1: Type, tp2: Type, op: (Type, Type) => Type, original: (Type, Type) => Type, combineVariance: (Variance, Variance) => Variance) = { val tparams1 = tp1.typeParams val tparams2 = tp2.typeParams diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 777f43931e13..6757e3170f91 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1018,8 +1018,11 @@ object Types { */ def safe_& (that: Type)(using Context): Type = (this, that) match { case (TypeBounds(lo1, hi1), TypeBounds(lo2, hi2)) => - TypeBounds(OrType(lo1.stripLazyRef, lo2.stripLazyRef), AndType(hi1.stripLazyRef, hi2.stripLazyRef)) - case _ => this & that + TypeBounds( + OrType.makeHk(lo1.stripLazyRef, lo2.stripLazyRef), + AndType.makeHk(hi1.stripLazyRef, hi2.stripLazyRef)) + case _ => + this & that } /** `this & that`, but handle CyclicReferences by falling back to `safe_&`. @@ -2934,6 +2937,10 @@ object Types { tp2 else if (checkValid) apply(tp1, tp2) else unchecked(tp1, tp2) + + /** Like `make`, but also supports higher-kinded types as argument */ + def makeHk(tp1: Type, tp2: Type)(using Context): Type = + ctx.typeComparer.liftIfHK(tp1, tp2, AndType.make(_, _, checkValid = false), makeHk, _ | _) } abstract case class OrType(tp1: Type, tp2: Type) extends AndOrType { @@ -3020,6 +3027,10 @@ object Types { def make(tp1: Type, tp2: Type)(using Context): Type = if (tp1 eq tp2) tp1 else apply(tp1, tp2) + + /** Like `make`, but also supports higher-kinded types as argument */ + def makeHk(tp1: Type, tp2: Type)(using Context): Type = + ctx.typeComparer.liftIfHK(tp1, tp2, OrType(_, _), makeHk, _ & _) } /** An extractor object to pattern match against a nullable union. diff --git a/tests/pending/pos/i9346.scala b/tests/pending/pos/i9346.scala new file mode 100644 index 000000000000..51e747fd976e --- /dev/null +++ b/tests/pending/pos/i9346.scala @@ -0,0 +1,9 @@ +trait Foo[+A] { + type Repr[+O] <: Foo[O] { + type Repr[+OO] = Foo.this.Repr[OO] + } + + def foo: Repr[A] + + def bar: Repr[A] = this.foo.foo +}