Skip to content

Commit 1633ccd

Browse files
dwijnandWojciechMazur
authored andcommitted
Allow autotupling if fn's param is a type param
[Cherry-picked 9d2aeac]
1 parent b8a10a4 commit 1633ccd

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed

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

+13-1
Original file line numberDiff line numberDiff line change
@@ -2237,7 +2237,19 @@ trait Applications extends Compatibility {
22372237

22382238
def isCorrectUnaryFunction(alt: TermRef): Boolean =
22392239
val formals = params(alt)
2240-
formals.length == 1 && ptIsCorrectProduct(formals.head, args)
2240+
formals.length == 1 && {
2241+
formals.head match
2242+
case formal: TypeParamRef =>
2243+
// While `formal` isn't a tuple type of the correct arity,
2244+
// it's a type parameter (a method type parameter presumably)
2245+
// so check its bounds allow for a tuple type of the correct arity.
2246+
// See i21682 for an example.
2247+
val tup = defn.tupleType(args.map(v => if v.tpt.isEmpty then WildcardType else typedAheadType(v.tpt).tpe))
2248+
val TypeBounds(lo, hi) = formal.paramInfo
2249+
lo <:< tup && tup <:< hi
2250+
case formal =>
2251+
ptIsCorrectProduct(formal, args)
2252+
}
22412253

22422254
val numArgs = args.length
22432255
if numArgs > 1

tests/pos/i21682.1.scala

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
sealed abstract class Gen[+T1]
2+
given [T2]: Conversion[T2, Gen[T2]] = ???
3+
4+
trait Show[T3]
5+
given Show[Boolean] = ???
6+
given [A1: Show, B1: Show, C1: Show]: Show[(A1, B1, C1)] = ???
7+
8+
object ForAll:
9+
def apply[A2: Show, B2](f: A2 => B2): Unit = ???
10+
def apply[A3: Show, B3: Show, C3](f: (A3, B3) => C3): Unit = ???
11+
def apply[A4: Show, B4](gen: Gen[A4])(f: A4 => B4): Unit = ???
12+
13+
@main def Test =
14+
ForAll: (b1: Boolean, b2: Boolean, b3: Boolean) =>
15+
???

tests/pos/i21682.2.scala

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object ForAll:
2+
def apply[A1, B](f: A1 => B): Unit = ???
3+
def apply[A1, A2, B](f: (A1, A2) => B): Unit = ???
4+
5+
@main def Test =
6+
ForAll: (b1: Boolean, b2: Boolean, b3: Boolean) =>
7+
???

tests/pos/i21682.3.scala

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Test:
2+
def foo[A1 >: (Nothing, Boolean, Nothing) <: (Any, Boolean, Any), B](f: A1 => B): Unit = ???
3+
def test(): Unit =
4+
val res4 = this.foo((b1: Boolean, b2: Boolean, b3: Boolean) => ???)

0 commit comments

Comments
 (0)