diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 9e0d501db19d..7ece15ddd0f8 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2449,7 +2449,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer // wrt to operand order for `&`, we include the explicit subtype test here. // See also #5649. then body1.tpe - else pt & body1.tpe + else body1.tpe & pt val sym = newPatternBoundSymbol(name, symTp, tree.span) if (pt == defn.ImplicitScrutineeTypeRef || tree.mods.is(Given)) sym.setFlag(Given) if (ctx.mode.is(Mode.InPatternAlternative)) diff --git a/tests/pos/i24038a.scala b/tests/pos/i24038a.scala new file mode 100644 index 000000000000..9386e7d98751 --- /dev/null +++ b/tests/pos/i24038a.scala @@ -0,0 +1,31 @@ +final class MBufferLong: + final def +=(elem: Long): this.type = ??? + +type M[Tup <: Tuple] <: Tuple = Tup match + case EmptyTuple => EmptyTuple + case h *: t => BufferOf[h] *: M[t] + +type M2[T <: Tuple] <: Tuple = (T, M[T]) match + case (h *: t, a *: b) => BufferOf[h] *: M2[t] + case (EmptyTuple, EmptyTuple) => EmptyTuple + case (_, EmptyTuple) => EmptyTuple + case (EmptyTuple, _) => EmptyTuple + +type BufferOf[T] = T match + case Long => MBufferLong + +inline def append[T](t: T, buffer: BufferOf[T]): BufferOf[T] = + inline (t, buffer) match + case (x: Long, y: BufferOf[Long]) => y.+=(x) + buffer + +transparent inline def appendBuffers[T <: Tuple](t: T, buffers: M[T]): M2[T] = { + inline (t, buffers) match + case abcd: ((h *: t), bh *: bt) => + val (hh *: tt, bh *: bt) = abcd + val x: BufferOf[h] = append[h](hh, bh.asInstanceOf[BufferOf[h]]) + x *: appendBuffers[t](tt, bt.asInstanceOf[M[t]]) + case _: (EmptyTuple, EmptyTuple) => EmptyTuple + case _: (_, EmptyTuple) => EmptyTuple + case _: (EmptyTuple, _) => EmptyTuple +} diff --git a/tests/pos/i24038b.scala b/tests/pos/i24038b.scala new file mode 100644 index 000000000000..ec0d12a4689b --- /dev/null +++ b/tests/pos/i24038b.scala @@ -0,0 +1,12 @@ +final class MBufferLong + +type M[Tup <: Tuple] <: Tuple = Tup match + case EmptyTuple => EmptyTuple + case h *: t => MBufferLong *: M[t] + +def appendBuffers[T <: Tuple](t: T, buffers: M[T]): Unit = { + (t, buffers) match + case abcd: (h *: t, bh *: bt) => + val (hh *: tt, bh *: bt) = abcd + summon[hh.type <:< h] +} diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index 539c9e977932..71e261b93c23 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -4930,8 +4930,8 @@ _empty_/Txn# => trait Txn [typeparam T <: Txn[T]] extends Object { self: Txn[T] _empty_/Txn#[T] => typeparam T <: Txn[T] _empty_/Txn#``(). => primary ctor [typeparam T <: Txn[T]](): Txn[T] local0 => val local out: Repr[Out] -local1 => val local inObj: Repr[In] & Obj[In] -local2 => val local outObj: Repr[Out] & Obj[Out] +local1 => val local inObj: Obj[In] & Repr[In] +local2 => val local outObj: Obj[Out] & Repr[Out] Occurrences: [1:6..1:9): Txn <- _empty_/Txn#