@@ -18,6 +18,7 @@ import annotation.{tailrec, constructorOnly}
1818import ast .tpd
1919import ast .tpd .*
2020import Synthesizer .*
21+ import TypeComparer .{fullLowerBound , fullUpperBound }
2122
2223/** Synthesize terms for special classes */
2324class Synthesizer (typer : Typer )(using @ constructorOnly c : Context ):
@@ -36,10 +37,32 @@ class Synthesizer(typer: Typer)(using @constructorOnly c: Context):
3637 // bounds are usually widened during instantiation.
3738 instArg(tp.tp1)
3839 case tvar : TypeVar if ctx.typerState.constraint.contains(tvar) =>
40+ // If tvar has a lower or upper bound:
41+ // 1. If the bound is not another type variable, use this as approximation.
42+ // 2. Otherwise, if the type can be forced to be fully defined, use that type
43+ // as approximation.
44+ // 3. Otherwise leave argument uninstantiated.
45+ // The reason for (2) is that we observed complicated constraints in i23611.scala
46+ // that get better types if a fully defined type is computed than if several type
47+ // variables are approximated incrementally. This is a minimization of some ZIO code.
48+ // So in order to keep backwards compatibility (where before we _only_ did 2) we
49+ // add that special case.
50+ def isGroundConstr (tp : Type ): Boolean = tp.dealias match
51+ case tvar : TypeVar if ctx.typerState.constraint.contains(tvar) => false
52+ case pref : TypeParamRef if ctx.typerState.constraint.contains(pref) => false
53+ case tp : AndOrType => isGroundConstr(tp.tp1) && isGroundConstr(tp.tp2)
54+ case _ => true
3955 instArg(
40- if tvar.hasLowerBound then tvar.instantiate(fromBelow = true )
41- else if tvar.hasUpperBound then tvar.instantiate(fromBelow = false )
42- else NoType )
56+ if tvar.hasLowerBound then
57+ if isGroundConstr(fullLowerBound(tvar.origin)) then tvar.instantiate(fromBelow = true )
58+ else if isFullyDefined(tp, ForceDegree .all) then tp
59+ else NoType
60+ else if tvar.hasUpperBound then
61+ if isGroundConstr(fullUpperBound(tvar.origin)) then tvar.instantiate(fromBelow = false )
62+ else if isFullyDefined(tp, ForceDegree .all) then tp
63+ else NoType
64+ else
65+ NoType )
4366 case _ =>
4467 tp
4568
0 commit comments