diff --git a/compiler/src/dotty/tools/dotc/core/TypeUtils.scala b/compiler/src/dotty/tools/dotc/core/TypeUtils.scala index 739cc2b74a16..ab035db68d9f 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeUtils.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeUtils.scala @@ -68,7 +68,7 @@ class TypeUtils: def tupleElementTypesUpTo(bound: Int, normalize: Boolean = true)(using Context): Option[List[Type]] = def recur(tp: Type, bound: Int): Option[List[Type]] = if bound < 0 then Some(Nil) - else (if normalize then tp.normalized else tp).dealias match + else (if normalize then tp.dealias.normalized else tp).dealias match case AppliedType(tycon, hd :: tl :: Nil) if tycon.isRef(defn.PairClass) => recur(tl, bound - 1).map(hd :: _) case tp: AppliedType if defn.isTupleNType(tp) && normalize => diff --git a/compiler/test/dotc/pos-test-pickling.excludelist b/compiler/test/dotc/pos-test-pickling.excludelist index 23c79affada0..28bce963bfd1 100644 --- a/compiler/test/dotc/pos-test-pickling.excludelist +++ b/compiler/test/dotc/pos-test-pickling.excludelist @@ -71,6 +71,7 @@ i18211.scala named-tuples1.scala i20897.scala i20512.scala +i22645b.scala # Opaque type i5720.scala diff --git a/tests/pos/i22643.scala b/tests/pos/i22643.scala new file mode 100644 index 000000000000..5b203c678740 --- /dev/null +++ b/tests/pos/i22643.scala @@ -0,0 +1,48 @@ +import language.experimental.namedTuples + + + +object ExhibitB: + + trait JoinB[A <: Tuple, B <: Tuple]: + type NTB = NamedTuple.NamedTuple[Tuple.Concat[A, B], (String, Int)] + val ntB: NTB = ??? + + val joinB: JoinB[Tuple1["nameB"], Tuple1["ageB"]] = ??? + + joinB.ntB.nameB // works + + +object ExhibitC: + + type A = Tuple1["nameC"] + type B = Tuple1["ageC"] + + type NamesC = Tuple.Concat[A, B] + type NTC = NamedTuple.NamedTuple[NamesC, (String, Int)] + val ntC: NTC = ??? + + ntC.nameC // works + + +object ExhibitD: + + trait JoinD[A, B]: + type NamesD = (A, B) + type NTD = NamedTuple.NamedTuple[NamesD, (String, Int)] + val ntD: NTD = ??? + + val joinD: JoinD["nameD", "ageD"] = ??? + + joinD.ntD.nameD // works + +object ExhibitA: + + trait JoinA[A <: Tuple, B <: Tuple]: + type NamesA = Tuple.Concat[A, B] + type NTA = NamedTuple.NamedTuple[NamesA, (String, Int)] + val ntA: NTA = ??? + + val joinA: JoinA[Tuple1["nameA"], Tuple1["ageA"]] = ??? + + joinA.ntA.nameA // fixed diff --git a/tests/pos/i22645a.scala b/tests/pos/i22645a.scala new file mode 100644 index 000000000000..3015d7dd161c --- /dev/null +++ b/tests/pos/i22645a.scala @@ -0,0 +1,44 @@ +import language.experimental.namedTuples +object ExhibitA: // fails + + class SelectableNT[N <: Tuple] extends Selectable: + def selectDynamic(name: String) = ??? + type Names = Tuple.Map[N, [X] =>> X] + type Fields = NamedTuple.NamedTuple[Names, (String, Int)] + + val x = new SelectableNT[("name", "age")] + x.name // fails + + +object ExhibitB: // works + + class SelectableNT[N <: Tuple] extends Selectable: + def selectDynamic(name: String) = ??? + type Fields = NamedTuple.NamedTuple[N, (String, Int)] + + val x = new SelectableNT[("name", "age")] + x.name + + +object ExhibitC: // works + + class SelectableNT[N <: Tuple] extends Selectable: + def selectDynamic(name: String) = ??? + type Fields = NamedTuple.NamedTuple[N, (String, Int)] + + type N = ("name", "age") + val x = new SelectableNT[N] + x.name + + +object ExhibitD: // works + + class SelectableNT[N <: Tuple] extends Selectable: + def selectDynamic(name: String) = ??? + type Fields = NamedTuple.NamedTuple[N, (String, Int)] + + type N = ("name", "age") + type Names = Tuple.Map[N, [X] =>> X] + val x = new SelectableNT[Names] + x.name + diff --git a/tests/pos/i22645b.scala b/tests/pos/i22645b.scala new file mode 100644 index 000000000000..acce89f25ee9 --- /dev/null +++ b/tests/pos/i22645b.scala @@ -0,0 +1,12 @@ +import language.experimental.namedTuples +object ExhibitE: // works + + type N = ("name", "age") + type Names = Tuple.Map[N, [X] =>> X] + + class SelectableNT extends Selectable: + def selectDynamic(name: String) = ??? + type Fields = NamedTuple.NamedTuple[Names, (String, Int)] + + val x = new SelectableNT + x.name \ No newline at end of file