@@ -201,17 +201,19 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
201201 /** Map parametric functions with results that have a capture set somewhere
202202 * to dependent functions.
203203 */
204- protected def normalizeFunctions (tp : Type , original : Type )(using Context ): Type = tp match
204+ protected def normalizeFunctions (tp : Type , original : Type , expandAlways : Boolean = false )(using Context ): Type =
205+ tp match
205206 case AppliedType (tycon, args)
206207 if defn.isNonRefinedFunction(tp) && isTopLevel =>
207- original match
208- case AppliedType (`tycon`, args0) if args0.last ne args.last =>
209- // We have an applied type that underwent some addition of capture sets.
210- // Map to a dependent type so that things are more uniform.
211- depFun(args.init, args.last,
212- isContextual = defn.isContextFunctionClass(tycon.classSymbol))
213- .showing(i " add function refinement $tp ( $tycon, ${args.init}, ${args.last}) --> $result" , capt)
214- case _ => tp
208+ // Expand if we have an applied type that underwent some addition of capture sets
209+ val expand = expandAlways || original.match
210+ case AppliedType (`tycon`, args0) => args0.last ne args.last
211+ case _ => false
212+ if expand then
213+ depFun(args.init, args.last,
214+ isContextual = defn.isContextFunctionClass(tycon.classSymbol))
215+ .showing(i " add function refinement $tp ( $tycon, ${args.init}, ${args.last}) --> $result" , capt)
216+ else tp
215217 case _ => tp
216218
217219 /** Pull out an embedded capture set from a part of `tp` */
@@ -334,8 +336,11 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
334336 def fail (msg : Message ) =
335337 if ! tptToCheck.isEmpty then report.error(msg, tptToCheck.srcPos)
336338
337- val toCapturing = new DeepTypeMap with SetupTypeMap :
338- override def toString = " expand aliases"
339+ object toCapturing extends DeepTypeMap , SetupTypeMap :
340+ override def toString = " transformExplicitType"
341+
342+ var keepFunAliases = true
343+ var keptFunAliases = false
339344
340345 /** Expand $throws aliases. This is hard-coded here since $throws aliases in stdlib
341346 * are defined with `?=>` rather than `?->`.
@@ -425,21 +430,33 @@ class Setup extends PreRecheck, SymTransformer, SetupAPI:
425430 case throwsAlias(res, exc) =>
426431 this (expandThrowsAlias(res, exc, Nil ))
427432 case t @ AppliedType (tycon, args)
428- if defn.isNonRefinedFunction(tp)
429- && ! defn.isFunctionSymbol(tp.typeSymbol) && (tp.dealias ne tp) =>
430- // Expand arguments of aliases of function types before proceeding with dealias.
431- // This is necessary to bind existentialFresh instances to the right method binder.
432- val args1 = atVariance(- variance):
433- args.map(this )
434- defaultApply(t.derivedAppliedType(tycon, args1))
433+ if defn.isNonRefinedFunction(t)
434+ && ! defn.isFunctionSymbol(t.typeSymbol) && (t.dealias ne tp) =>
435+ if keepFunAliases then
436+ // Hold off with dealising and expand in a second pass.
437+ // This is necessary to bind existentialFresh instances to the right method binder.
438+ keptFunAliases = true
439+ mapOver(t)
440+ else
441+ // In the second pass, map the alias and make sure it has the form
442+ // of a dependent function.
443+ normalizeFunctions(apply(t.dealias), t, expandAlways = true )
435444 case t =>
436445 defaultApply(t)
437446 end toCapturing
438447
439- val tp1 = toCapturing(tp)
440- val tp2 = Existential .mapCapInResults(fail)(tp1)
441- if tp2 ne tp then capt.println(i " expanded explicit in ${ctx.owner}: $tp --> $tp1 --> $tp2" )
442- tp2
448+ def transform (tp : Type ): Type =
449+ val tp1 = toCapturing(tp)
450+ val tp2 = Existential .mapCapInResults(fail, toCapturing.keepFunAliases)(tp1)
451+ val snd = if toCapturing.keepFunAliases then " " else " 2nd time"
452+ if tp2 ne tp then capt.println(i " expanded explicit $snd in ${ctx.owner}: $tp --> $tp1 --> $tp2" )
453+ tp2
454+
455+ val tp1 = transform(tp)
456+ if toCapturing.keptFunAliases then
457+ toCapturing.keepFunAliases = false
458+ transform(tp1)
459+ else tp1
443460 end transformExplicitType
444461
445462 /** Substitute parameter symbols in `from` to paramRefs in corresponding
0 commit comments