@@ -7,7 +7,7 @@ import core.*
77import  Constants .* , Contexts .* , Decorators .* , Flags .* , NullOpsDecorator .* , Symbols .* , Types .* 
88import  Names .* , NameOps .* , StdNames .* 
99import  ast .* , tpd .* 
10- import  config .Printers .* 
10+ import  config .Printers .exhaustivity 
1111import  printing .{ Printer , *  }, Texts .* 
1212import  reporting .* 
1313import  typer .* , Applications .* , Inferencing .* , ProtoTypes .* 
@@ -524,14 +524,36 @@ object SpaceEngine {
524524    val  mt :  MethodType  =  unapp.widen match  {
525525      case  mt : MethodType  =>  mt
526526      case  pt : PolyType    => 
527+         if  unappSym.is(Synthetic ) then 
528+           val  mt  =  pt.resultType.asInstanceOf [MethodType ]
529+           val  unapplyArgType  =  mt.paramInfos.head
530+           val  targs  =  scrutineeTp.baseType(unapplyArgType.classSymbol) match 
531+             case  AppliedType (_, targs) =>  targs
532+             case  _ => 
533+               //  Typically when the scrutinee is Null or Nothing (see i5067 and i5067b)
534+               //  For performance, do `variances(unapplyArgType)` but without using TypeVars
535+               //  so just find the variance, so we know if to min/max to the LB/UB or use a wildcard.
536+               object  accu  extends  TypeAccumulator [VarianceMap [TypeParamRef ]]: 
537+                 def  apply (vmap : VarianceMap [TypeParamRef ], tp : Type ) =  tp match 
538+                   case  tp : TypeParamRef  if  tp.binder eq pt =>  vmap.recordLocalVariance(tp, variance)
539+                   case  _                                   =>  foldOver(vmap, tp)
540+               val  vs  =  accu(VarianceMap .empty[TypeParamRef ], unapplyArgType)
541+               pt.paramRefs.map:  p => 
542+                 vs.computedVariance(p).uncheckedNN match 
543+                   case  - 1  =>  p.paramInfo.lo
544+                   case  1   =>  p.paramInfo.hi
545+                   case  _  =>  WildcardType (p.paramInfo)
546+           pt.instantiate(targs).asInstanceOf [MethodType ]
547+         else 
527548          val  locked  =  ctx.typerState.ownedVars
528549          val  tvars  =  constrained(pt)
529550          val  mt  =  pt.instantiate(tvars).asInstanceOf [MethodType ]
530-           scrutineeTp <:<  mt.paramInfos(0 )
551+           val  unapplyArgType  =  mt.paramInfos.head
552+           scrutineeTp <:<  unapplyArgType
531553          //  force type inference to infer a narrower type: could be singleton
532554          //  see tests/patmat/i4227.scala
533-           mt.paramInfos( 0 )  <:<  scrutineeTp
534-           maximizeType(mt.paramInfos( 0 ) , Spans .NoSpan )
555+           unapplyArgType  <:<  scrutineeTp
556+           maximizeType(unapplyArgType , Spans .NoSpan )
535557          if  ! (ctx.typerState.ownedVars --  locked).isEmpty then 
536558            //  constraining can create type vars out of wildcard types
537559            //  (in legalBound, by using a LevelAvoidMap)
@@ -543,7 +565,7 @@ object SpaceEngine {
543565            //  but I'd rather have an unassigned new-new type var, than an infinite loop.
544566            //  After all, there's nothing strictly "wrong" with unassigned type vars,
545567            //  it just fails TreeChecker's linting.
546-             maximizeType(mt.paramInfos( 0 ) , Spans .NoSpan )
568+             maximizeType(unapplyArgType , Spans .NoSpan )
547569          mt
548570    }
549571
0 commit comments