Skip to content

Commit 9322e8c

Browse files
authored
Merge pull request #7985 from dotty-staging/fix-#7969
Fix #7969: Don't let Typevars be bounded by ExprTypes
2 parents 193f7de + 84e5422 commit 9322e8c

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,17 @@ trait ConstraintHandling[AbstractContext] {
508508
case inst =>
509509
prune(inst)
510510
}
511+
case bound: ExprType =>
512+
// ExprTypes are not value types, so type parameters should not
513+
// be instantiated to ExprTypes. A scenario where such an attempted
514+
// instantiation can happen is if we unify (=> T) => () with A => ()
515+
// where A is a TypeParamRef. See the comment on EtaExpansion.etaExpand
516+
// why types such as (=> T) => () can be constructed and i7969.scala
517+
// as a test where this happens.
518+
// Note that scalac by contrast allows such instantiations. But letting
519+
// type variables be ExprTypes has its own problems (e.g. you can't write
520+
// the resulting types down) and is largely unknown terrain.
521+
NoType
511522
case _ =>
512523
pruneLambdaParams(bound)
513524
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,19 @@ object EtaExpansion extends LiftImpure {
198198
* In each case, the result is an untyped tree, with `es` and `expr` as typed splices.
199199
*
200200
* F[V](x) ==> (x => F[X])
201+
*
202+
* Note: We allow eta expanding a method with a call by name parameter like
203+
*
204+
* def m(x: => T): T
205+
*
206+
* to a value of type (=> T) => T. This type cannot be written in source, since
207+
* by-name types => T are not legal argument types.
208+
*
209+
* It would be simpler to not allow to eta expand by-name methods. That was the rule
210+
* initially, but at some point, the rule was dropped. Enforcing the restriction again
211+
* now would break existing code. Allowing by-name parameters in function types seems to
212+
* be OK. After elimByName they are all converted to regular function types anyway.
213+
* But see comment on the `ExprType` case in function `prune` in class `ConstraintHandling`.
201214
*/
202215
def etaExpand(tree: Tree, mt: MethodType, xarity: Int)(implicit ctx: Context): untpd.Tree = {
203216
import untpd._

tests/neg/i7969.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object O{
2+
def f(i: => Int): Int = 1
3+
def m[A](a: A => Int) = 2
4+
def n = m(f) // error: cannot eta expand
5+
}

0 commit comments

Comments
 (0)