@@ -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