From 2e3783550d01407de13701003ba84467ec8aa258 Mon Sep 17 00:00:00 2001 From: Matt Bovel Date: Thu, 25 May 2023 19:48:44 +0200 Subject: [PATCH 1/4] Use AllowLambdaWildcardApply mode in ApproximatingTypeMap Co-Authored-By: Guillaume Martres <63430+smarter@users.noreply.github.com> Co-Authored-By: Dale Wijnand Co-Authored-By: Decel <8268812+Decel@users.noreply.github.com> --- compiler/src/dotty/tools/dotc/core/Types.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 04dfbbb26ef7..ef6f78afc372 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -6045,7 +6045,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 From b3f210247bcc342b03600dd28ccc95f52f5cddb7 Mon Sep 17 00:00:00 2001 From: Matt Bovel Date: Wed, 21 Jun 2023 10:49:16 +0200 Subject: [PATCH 2/4] Normalize types in compareAtoms Revert "Normalize types in compareAtoms" This reverts commit 1b52634d980de3e8c012ccde95e1a9dbebd17400. f Co-Authored-By: Dale Wijnand --- compiler/src/dotty/tools/dotc/core/Types.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index ef6f78afc372..71a05897276f 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 From 0258dc3e046be1b71453b05cdcdff24941333b6a Mon Sep 17 00:00:00 2001 From: Matt Bovel Date: Wed, 21 Jun 2023 11:38:16 +0200 Subject: [PATCH 3/4] Widen skolem in scrutinee when normalizing match aliase Co-Authored-By: Dale Wijnand --- compiler/src/dotty/tools/dotc/core/Types.scala | 10 +++++++++- tests/pos/16583.scala | 15 +++++++++++++++ tests/pos/16654.scala | 7 +++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/pos/16583.scala create mode 100644 tests/pos/16654.scala diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 71a05897276f..ec2066ab41dc 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -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 _ => 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 +} From a47a5478b9efdcd9a893cb4e4446ef7ca8a01777 Mon Sep 17 00:00:00 2001 From: Matt Bovel Date: Wed, 21 Jun 2023 11:38:38 +0200 Subject: [PATCH 4/4] Widen skolem in scrutinee when reducing or comparing match types Co-Authored-By: Dale Wijnand --- compiler/src/dotty/tools/dotc/core/TypeComparer.scala | 2 +- compiler/src/dotty/tools/dotc/core/Types.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 ec2066ab41dc..0b963b74a4ac 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -4954,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