diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index a0922c1f0574..932246252ca5 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -1007,7 +1007,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling case tp1: MatchType => def compareMatch = tp2 match { case tp2: MatchType => - isSameType(tp1.scrutinee, tp2.scrutinee) && + isSameType(tp1.scrutinee.widenSkolem, tp2.scrutinee.widenSkolem) && tp1.cases.corresponds(tp2.cases)(isSubType) case _ => false } diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 04dfbbb26ef7..0b963b74a4ac 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1373,7 +1373,7 @@ object Types { Atoms.Range(set, set) else Atoms.Unknown - dealias match + dealias.normalized match case tp: SingletonType => tp.underlying.atoms match case as @ Atoms.Range(lo, hi) => @@ -1456,7 +1456,7 @@ object Types { deskolemizer(this) /** The result of normalization using `tryNormalize`, or the type itself if - * tryNormlize yields NoType + * tryNormalize yields NoType */ final def normalized(using Context): Type = { val normed = tryNormalize @@ -4478,7 +4478,15 @@ object Types { case MatchAlias(alias) => trace(i"normalize $this", typr, show = true) { MatchTypeTrace.recurseWith(this) { - alias.applyIfParameterized(args.map(_.normalized)).tryNormalize + alias.applyIfParameterized(args.map(_.normalized)) match + case mt @ MatchType(bound, scrutinee, cases) => + val scrutinee1 = scrutinee.widenSkolem + if scrutinee1 ne scrutinee then + mt.derivedMatchType(bound, scrutinee.widenSkolem, cases).normalized + else + mt.tryNormalize + case mt => + mt.tryNormalize } } case _ => @@ -4946,7 +4954,7 @@ object Types { trace(i"reduce match type $this $hashCode", matchTypes, show = true) { def matchCases(cmp: TrackingTypeComparer): Type = val saved = ctx.typerState.snapshot() - try cmp.matchCases(scrutinee.normalized, cases) + try cmp.matchCases(scrutinee.normalized.widenSkolem, cases) catch case ex: Throwable => handleRecursive("reduce type ", i"$scrutinee match ...", ex) finally @@ -6045,7 +6053,7 @@ object Types { case _ => if args.exists(isRange) then if variance > 0 then - tp.derivedAppliedType(tycon, args.map(rangeToBounds)) match + tp.derivedAppliedType(tycon, args.map(rangeToBounds))(using ctx.addMode(Mode.AllowLambdaWildcardApply)) match case tp1: AppliedType if tp1.isUnreducibleWild && ctx.phase != checkCapturesPhase => // don't infer a type that would trigger an error later in // Checking.checkAppliedType; fall through to default handling instead diff --git a/tests/pos/16583.scala b/tests/pos/16583.scala new file mode 100644 index 000000000000..fe862ccac899 --- /dev/null +++ b/tests/pos/16583.scala @@ -0,0 +1,15 @@ +import scala.compiletime.constValueTuple + +val ll0: Tuple3["one", "two", "three"] = constValueTuple[("one", "two", "three")] +val ll1 = constValueTuple[("one", "two", "three")].toList +val ll3: List["one" | ("two" | ("three" | Nothing))] = constValueTuple[("one", "two", "three")].toList +val ll4: List["one" | ("two" | "three")] = constValueTuple[("one", "two", "three")].toList + +inline def labels[Labels <: Tuple](using ev: Tuple.Union[Labels] <:< String): List[String] = + val tmp = constValueTuple[Labels].toList + ev.substituteCo( tmp ) + +def test = labels[("one", "two", "three")] + +def toList(x: Tuple): List[Tuple.Union[x.type]] = ??? +def test2[Labels <: Tuple] = toList((???): Labels) diff --git a/tests/pos/16654.scala b/tests/pos/16654.scala new file mode 100644 index 000000000000..9234c309de88 --- /dev/null +++ b/tests/pos/16654.scala @@ -0,0 +1,7 @@ +def toCsvFlat[A <: Product](a: A)(using m: scala.deriving.Mirror.ProductOf[A]) = { + def flatTuple(any: Any): Tuple = any match + case p: Product => p.productIterator.map(flatTuple).foldLeft(EmptyTuple: Tuple)(_ ++ _) + case a => Tuple1(a) + + val tuple = flatTuple(Tuple.fromProductTyped(a)).toList +}