From e25f9fd973df2845d5f9c973aafb490a7c13427f Mon Sep 17 00:00:00 2001 From: odersky Date: Tue, 31 May 2022 18:20:34 +0200 Subject: [PATCH] Revert "Remove now-unnecessary `avoid` when typing closures" This reverts commit 629006b3e5c456d5073e5eda2fa9c39ddc32a135. --- compiler/src/dotty/tools/dotc/typer/Namer.scala | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 4797f153d0a2..cf0a40fe8b79 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1672,7 +1672,22 @@ class Namer { typer: Typer => // This case applies if the closure result type contains uninstantiated // type variables. In this case, constrain the closure result from below // by the parameter-capture-avoiding type of the body. - typedAheadExpr(mdef.rhs, tpt.tpe).tpe + val rhsType = typedAheadExpr(mdef.rhs, tpt.tpe).tpe + + // The following part is important since otherwise we might instantiate + // the closure result type with a plain functon type that refers + // to local parameters. An example where this happens in `dependent-closures.scala` + // If the code after `val rhsType` is commented out, this file fails pickling tests. + // AVOIDANCE TODO: Follow up why this happens, and whether there + // are better ways to achieve this. It would be good if we could get rid of this code. + // It seems at least partially redundant with the nesting level checking on TypeVar + // instantiation. + val hygienicType = TypeOps.avoid(rhsType, termParamss.flatten) + if (!hygienicType.isValueType || !(hygienicType <:< tpt.tpe)) + report.error(i"return type ${tpt.tpe} of lambda cannot be made hygienic;\n" + + i"it is not a supertype of the hygienic type $hygienicType", mdef.srcPos) + //println(i"lifting $rhsType over $termParamss -> $hygienicType = ${tpt.tpe}") + //println(TypeComparer.explained { implicit ctx => hygienicType <:< tpt.tpe }) case _ => } WildcardType