Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/core/TypeUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ class TypeUtils:
case _ =>
if defn.isTupleClass(tp.typeSymbol) && !normalize then Some(tp.dealias.argInfos)
else None
recur(self.stripTypeVar, bound)
val stripped = if normalize then self.stripTypeVar.dealias else self.stripTypeVar // keep error reporting aliased
recur(stripped, bound)

/** Is this a generic tuple but not already an instance of one of Tuple1..22? */
def isGenericTuple(using Context): Boolean =
Expand Down
48 changes: 48 additions & 0 deletions tests/pos/i22643.scala
Original file line number Diff line number Diff line change
@@ -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
44 changes: 44 additions & 0 deletions tests/pos/i22645a.scala
Original file line number Diff line number Diff line change
@@ -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

Loading