Skip to content

Commit 783189d

Browse files
Fix test, make new test that breaks
The case where the left side isn't a function type/ is a type param now works for non dependent type cases. HOWEVER, now the compiler rejects constructions like `untupled` for dependent types, when it should accept them. [skip community_build] [skip docs] [skip test_windows_fast] [skip mima]
1 parent 24e43b9 commit 783189d

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

compiler/src/dotty/tools/dotc/typer/Synthesizer.scala

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,25 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
178178
case _ => -1
179179
else if defn.isFunctionNType(tupled) then
180180
// TupledFunction[?, (...) => R]
181-
dealiasedTupled.argInfos match
182-
case tupledArgs :: funRet :: Nil =>
183-
// TupledFunction[?, ((...)) => R]
184-
tupledArgs.tupleElementTypes match
185-
case Some(args) if doesFunctionUntupleTo(dealiasedTupled, args, funRet, dealiasedFun) =>
186-
args.size
181+
dealiasedTupled match
182+
case defn.RefinedFunctionOf(method: MethodType) =>
183+
method.argInfos match
184+
case tupledArgs :: funRet :: Nil =>
185+
// TupledFunction[?, ((...)) => R]
186+
tupledArgs.tupleElementTypes match
187+
case Some(args) if doesFunctionUntupleTo(dealiasedTupled, args, funRet, dealiasedFun) =>
188+
args.size
189+
case _ => -1
190+
case _ => -1
191+
case _ =>
192+
tupled.functionArgInfos match
193+
case tupledArgs :: funRet :: Nil =>
194+
// TupledFunction[?, ((...)) => R]
195+
tupledArgs.tupleElementTypes match
196+
case Some(args) if functionTypeEqual(dealiasedTupled, args, funRet, dealiasedFun) =>
197+
args.size
198+
case _ => -1
187199
case _ => -1
188-
case _ => -1
189200
else
190201
// TupledFunction[?, ?]
191202
-1

tests/run/i21808.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//> using options -experimental
2+
3+
import scala.util.TupledFunction
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
7+
val f2: (x: (Int, Long)) => x._1.type = (args: (Int, Long)) => args._1
8+
val g2: (x: Int, y: Long) => x.type = f2.untupled
9+
println(g2(1, 3L))
10+
11+
}
12+
13+
/** Creates an untupled version of this function: instead of a single argument of type [[scala.Tuple]] with N elements,
14+
* it accepts N arguments.
15+
*
16+
* This is a generalization of [[scala.Function.untupled]] that work on functions of any arity
17+
*
18+
* @tparam F the function type
19+
* @tparam Args the tuple type with the same types as the function arguments of F
20+
* @tparam R the return type of F
21+
*/
22+
extension [F, Args <: Tuple, R](f: Args => R) def untupled(using tf: TupledFunction[F, Args => R]): F = tf.untupled(f)
23+
}

0 commit comments

Comments
 (0)