File tree 3 files changed +29
-0
lines changed
compiler/src/dotty/tools/dotc
3 files changed +29
-0
lines changed Original file line number Diff line number Diff line change @@ -508,6 +508,17 @@ trait ConstraintHandling[AbstractContext] {
508
508
case inst =>
509
509
prune(inst)
510
510
}
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
511
522
case _ =>
512
523
pruneLambdaParams(bound)
513
524
}
Original file line number Diff line number Diff line change @@ -198,6 +198,19 @@ object EtaExpansion extends LiftImpure {
198
198
* In each case, the result is an untyped tree, with `es` and `expr` as typed splices.
199
199
*
200
200
* 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`.
201
214
*/
202
215
def etaExpand (tree : Tree , mt : MethodType , xarity : Int )(implicit ctx : Context ): untpd.Tree = {
203
216
import untpd ._
Original file line number Diff line number Diff line change
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
+ }
You can’t perform that action at this time.
0 commit comments