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