From 6df641ec0ce1b92c143eea45ba4291c0472d36f5 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Tue, 27 May 2025 14:25:04 -0700 Subject: [PATCH] Test inline method returning match type --- .../test/dotc/pos-test-pickling.excludelist | 1 + tests/neg/i17210.scala | 28 +++++++++++++ tests/pos/i17210.scala | 42 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/neg/i17210.scala create mode 100644 tests/pos/i17210.scala diff --git a/compiler/test/dotc/pos-test-pickling.excludelist b/compiler/test/dotc/pos-test-pickling.excludelist index 28bce963bfd1..df7abd0f593f 100644 --- a/compiler/test/dotc/pos-test-pickling.excludelist +++ b/compiler/test/dotc/pos-test-pickling.excludelist @@ -72,6 +72,7 @@ named-tuples1.scala i20897.scala i20512.scala i22645b.scala +i17210.scala # Opaque type i5720.scala diff --git a/tests/neg/i17210.scala b/tests/neg/i17210.scala new file mode 100644 index 000000000000..45a902d0b63b --- /dev/null +++ b/tests/neg/i17210.scala @@ -0,0 +1,28 @@ + +object BugReport: + trait Executor + trait Updatable[+A] + + def run(task: Executor ?=> Unit): Unit = () + def tupledFunction(a: Int, b: Int): Unit = () + def tupledSequence(f: ((Updatable[Int], Updatable[Int])) => Unit): Unit = () + + type UpdatableMap[T <: Tuple] = T match + case EmptyTuple => EmptyTuple + case h *: t => Updatable[h] *: UpdatableMap[t] + // eliminate the match type + type xUpdatableMap[_] = (Updatable[Int], Updatable[Int]) + + // so that expected type is satisfied, avoid eta-expansion and subsequent error + def liftAsTupledInThreads[A <: Tuple](f: A => Unit)(using e: Executor): UpdatableMap[A] => Unit = _ => () + // eliminate eta-expansion where the partial application returns a context function + def xliftAsTupledInThreads[A <: Tuple](f: A => Unit): Executor ?=> UpdatableMap[A] => Unit = _ => () + + run: + tupledSequence(liftAsTupledInThreads(tupledFunction.tupled)) // error + + run: + val lifted = liftAsTupledInThreads(tupledFunction.tupled) + // the expected type induces the symptom + //val lifted: ((Updatable[Int], Updatable[Int])) => Unit = liftAsTupledInThreads(tupledFunction.tupled) + tupledSequence(lifted) diff --git a/tests/pos/i17210.scala b/tests/pos/i17210.scala new file mode 100644 index 000000000000..588886496e4f --- /dev/null +++ b/tests/pos/i17210.scala @@ -0,0 +1,42 @@ + +object BugReport: + trait Executor + trait Updatable[+A] + + def run(task: Executor ?=> Unit): Unit = () + def tupledFunction(a: Int, b: Int): Unit = () + def tupledSequence(f: ((Updatable[Int], Updatable[Int])) => Unit): Unit = () + + type UpdatableMap[T <: Tuple] = T match + case EmptyTuple => EmptyTuple + case h *: t => Updatable[h] *: UpdatableMap[t] + // eliminate the match type + type xUpdatableMap[_] = (Updatable[Int], Updatable[Int]) + + // so that expected type is satisfied, avoid eta-expansion and subsequent error + transparent inline // presumably allows match type "expansion" before adaptation + def liftAsTupledInThreads[A <: Tuple](f: A => Unit)(using e: Executor): UpdatableMap[A] => Unit = _ => () + // eliminate eta-expansion where the partial application returns a context function + def xliftAsTupledInThreads[A <: Tuple](f: A => Unit): Executor ?=> UpdatableMap[A] => Unit = _ => () + + run: + tupledSequence(liftAsTupledInThreads(tupledFunction.tupled)) // was error + + run: + val lifted = liftAsTupledInThreads(tupledFunction.tupled) + // the expected type induces the symptom + //val lifted: ((Updatable[Int], Updatable[Int])) => Unit = liftAsTupledInThreads(tupledFunction.tupled) + tupledSequence(lifted) + +object BugReport2: + trait Executor + trait Updatable[+A] + + def run(task: Executor ?=> Unit): Unit = () + def function(a: Int): Unit = () + def normalSequence(f: Updatable[Int] => Unit): Unit = () + + def liftInThreads[A](f: A => Unit)(using e: Executor): Updatable[A] => Unit = _ => () + + run: + normalSequence(liftInThreads(function))