Skip to content

Commit a196167

Browse files
committed
Allow inferred parameter types always, when eta-expanding
Rather than drawing an exemption based on fully defined types, report the right function arity. This leads eta-expansion to leave off the type, so then the parameter type is inferred. In the test case pos/i18453 this leads to the type var ?A being instantiated to X, rather than ?A & ?B being constrained against X & Y, which leads to ?A being instantiated to X & Y - and then failing to find a Box[X & Y] in scope.
1 parent 38559d7 commit a196167

File tree

5 files changed

+21
-10
lines changed

5 files changed

+21
-10
lines changed

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4167,11 +4167,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
41674167
val funExpected = functionExpected
41684168
val arity =
41694169
if funExpected then
4170-
if !isFullyDefined(pt, ForceDegree.none) && isFullyDefined(wtp, ForceDegree.none) then
4171-
// if method type is fully defined, but expected type is not,
4172-
// prioritize method parameter types as parameter types of the eta-expanded closure
4173-
0
4174-
else defn.functionArity(ptNorm)
4170+
defn.functionArity(ptNorm)
41754171
else
41764172
val nparams = wtp.paramInfos.length
41774173
if nparams > 1

tests/neg/i5976.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
object Test {
22
def f(i: => Int) = i + i
3-
val res = List(42).map(f) // error
3+
val res = List(42).map(f)
44

55
val g: (=> Int) => Int = f
66
val h: Int => Int = g // error
7-
}
7+
}

tests/pos/i18453.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
trait Box[T]
2+
3+
class Test:
4+
def f[A, B](c: A => A & B)(using ba: Box[A]): Unit = ???
5+
6+
def g[X, Y](using bx: Box[X]): Unit =
7+
def d(t: X): X & Y = t.asInstanceOf[X & Y]
8+
f(d)

tests/pos/i18453.workaround.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
trait Box[T]
2+
3+
class Test:
4+
def f[A, B](c: A => A & B)(using ba: Box[A]): Unit = ???
5+
6+
def g[X, Y](using bx: Box[X]): Unit =
7+
def d(t: X): X & Y = t.asInstanceOf[X & Y]
8+
f(u => d(u))

tests/semanticdb/metac.expect

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,7 @@ Language => Scala
10701070
Symbols => 181 entries
10711071
Occurrences => 159 entries
10721072
Diagnostics => 1 entries
1073-
Synthetics => 6 entries
1073+
Synthetics => 5 entries
10741074

10751075
Symbols:
10761076
_empty_/Enums. => final object Enums extends Object { self: Enums.type => +30 decls }
@@ -1253,7 +1253,7 @@ _empty_/Enums.unwrap().(ev) => implicit given param ev: <:<[A, Option[B]]
12531253
_empty_/Enums.unwrap().(opt) => param opt: Option[A]
12541254
_empty_/Enums.unwrap().[A] => typeparam A
12551255
_empty_/Enums.unwrap().[B] => typeparam B
1256-
local0 => param x: Option[B]
1256+
local0 => param x: A
12571257

12581258
Occurrences:
12591259
[0:7..0:12): Enums <- _empty_/Enums.
@@ -1421,7 +1421,6 @@ Diagnostics:
14211421

14221422
Synthetics:
14231423
[52:9..52:13):Refl => *.unapply[Option[B]]
1424-
[52:31..52:50):identity[Option[B]] => *[Function1[A, Option[B]]]
14251424
[54:14..54:18):Some => *.apply[Some[Int]]
14261425
[54:14..54:34):Some(Some(1)).unwrap => *(given_<:<_T_T[Option[Int]])
14271426
[54:19..54:23):Some => *.apply[Int]

0 commit comments

Comments
 (0)