diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index e38fbbb4b355..2dc5da4871a5 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1441,9 +1441,12 @@ object Types extends TypeUtils { private def dealias1(keep: AnnotatedType => Context ?=> Boolean, keepOpaques: Boolean)(using Context): Type = this match { case tp: TypeRef => if (tp.symbol.isClass) tp + else if keepOpaques && tp.symbol.is(Opaque) then tp else tp.info match { - case TypeAlias(alias) if !(keepOpaques && tp.symbol.is(Opaque)) => + case TypeAlias(alias) => alias.dealias1(keep, keepOpaques) + case MatchAlias(alias: AppliedType) => + (alias: Type).dealias1(keep, keepOpaques) case _ => tp } case app @ AppliedType(tycon, _) => diff --git a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala index a97917e28771..616d764d18a2 100644 --- a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala +++ b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala @@ -446,16 +446,13 @@ object Inlines: evidence } - def unrollTupleTypes(tpe: Type): Option[List[Type]] = tpe.dealias match + def unrollTupleTypes(tpe: Type): Option[List[Type]] = tpe.dealias.normalized match case AppliedType(tycon, args) if defn.isTupleClass(tycon.typeSymbol) => Some(args) case AppliedType(tycon, head :: tail :: Nil) if tycon.isRef(defn.PairClass) => unrollTupleTypes(tail).map(head :: _) case tpe: TermRef if tpe.symbol == defn.EmptyTupleModule => Some(Nil) - case tpRef: TypeRef => tpRef.info match - case MatchAlias(alias) => unrollTupleTypes(alias.tryNormalize) - case _ => None case _ => None diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 0a26ea697a6a..5162b3fed1b9 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -661,15 +661,9 @@ trait ImplicitRunInfo: case t: TypeLambda => for p <- t.paramRefs do partSeen += p traverseChildren(t) - case t: MatchType => - traverseChildren(t) - traverse(t.normalized) - case MatchType.InDisguise(mt) - if !t.isInstanceOf[LazyRef] // skip recursive applications (eg. Tuple.Map) - => - traverse(mt) case t => traverseChildren(t) + traverse(t.normalized) catch case ex: Throwable => handleRecursive("collectParts of", t.show, ex) def apply(tp: Type): collection.Set[Type] = diff --git a/tests/pos/i17395-spec.ordered.scala b/tests/pos/i17395-spec.ordered.scala new file mode 100644 index 000000000000..6e6ae8dd1e59 --- /dev/null +++ b/tests/pos/i17395-spec.ordered.scala @@ -0,0 +1,17 @@ +trait ThingWithPart { type Part } +type PartField[A] = ThingWithPart { type Part = A } +type ExtractPart[B] = B match { case PartField[a] => a } + +trait TC[C] +object TC: + def tcForOptionPart[D](implicit tc: TC[ExtractPart[D]]): TC[Option[ExtractPart[D]]] = new {} + +class Value +object Value: + implicit val tcValue: TC[Value] = new {} + +class ValuePartHolder extends ThingWithPart { type Part = Value } + +class Test: + def t1: Unit = + val tc = TC.tcForOptionPart[ValuePartHolder] diff --git a/tests/pos/i19821.scala b/tests/pos/i19821.scala new file mode 100644 index 000000000000..2dbbd1c82447 --- /dev/null +++ b/tests/pos/i19821.scala @@ -0,0 +1,23 @@ +type F[X] = X match { case String => Option[Int] } +type G[X] = X match { case Option[x] => Int } + +trait T: + type S + val opt1: F[S] + val opt2: O1 + type O1 = F[S] + +class Test: + def test: Unit = + val t: T { type S = String } = ??? + + val i1: G[t.opt1.type] = ??? + val j1: Int = i1 + + val i2: G[t.opt2.type] = ??? + val j2: Int = i2 // was: +//[E007] Type Mismatch Error: tests/pos/i19821.scala:17:18 -------------------- +// val j2: Int = i2 +// ^^ +// Found: (i2 : G[(t.bar : t.O)]) +// Required: Int diff --git a/tests/pos/i19857.scala b/tests/pos/i19857.scala new file mode 100644 index 000000000000..aeb6e49111c6 --- /dev/null +++ b/tests/pos/i19857.scala @@ -0,0 +1,23 @@ +sealed trait DFTypeAny + +sealed trait DFTuple[T <: NonEmptyTuple] extends DFTypeAny + +sealed trait DFBit extends DFTypeAny + +sealed trait DFValOf[T] + +type Of[T] <: DFTypeAny = T match + case DFTypeAny => T & DFTypeAny + case Product => FromProduct[T] + +type JUSTVAL[T] = DFValOf[Of[T]] + +type FromProduct[T <: Product] <: DFTypeAny = T match + case NonEmptyTuple => DFTuple[Tuple.Map[T, JUSTVAL]] + +trait Width2[T] + +object Width2: + inline given [T]: Width2[T] = new Width2[T] {} + +val x = summon[Width2[Of[(DFBit, DFBit)]]]