From 7a20f6cb7b61dce6f157a77dfffee19305ea1a04 Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 1 Jun 2022 12:25:51 +0200 Subject: [PATCH] Revert "Remove now-unnecessary `avoid` when typing closures" More precisely, put it under a Config flag which is off by default. This reverts commit 629006b3e5c456d5073e5eda2fa9c39ddc32a135. --- .../src/dotty/tools/dotc/typer/Namer.scala | 18 +++++++++++++++++- 1 file changed, 17 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..1b523bb71cf5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1672,7 +1672,23 @@ 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. + if !Config.checkLevels then + 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