@@ -7,7 +7,7 @@ import core.*
7
7
import Constants .* , Contexts .* , Decorators .* , Flags .* , NullOpsDecorator .* , Symbols .* , Types .*
8
8
import Names .* , NameOps .* , StdNames .*
9
9
import ast .* , tpd .*
10
- import config .Printers .*
10
+ import config .Printers .exhaustivity
11
11
import printing .{ Printer , * }, Texts .*
12
12
import reporting .*
13
13
import typer .* , Applications .* , Inferencing .* , ProtoTypes .*
@@ -524,14 +524,36 @@ object SpaceEngine {
524
524
val mt : MethodType = unapp.widen match {
525
525
case mt : MethodType => mt
526
526
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
527
548
val locked = ctx.typerState.ownedVars
528
549
val tvars = constrained(pt)
529
550
val mt = pt.instantiate(tvars).asInstanceOf [MethodType ]
530
- scrutineeTp <:< mt.paramInfos(0 )
551
+ val unapplyArgType = mt.paramInfos.head
552
+ scrutineeTp <:< unapplyArgType
531
553
// force type inference to infer a narrower type: could be singleton
532
554
// 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 )
535
557
if ! (ctx.typerState.ownedVars -- locked).isEmpty then
536
558
// constraining can create type vars out of wildcard types
537
559
// (in legalBound, by using a LevelAvoidMap)
@@ -543,7 +565,7 @@ object SpaceEngine {
543
565
// but I'd rather have an unassigned new-new type var, than an infinite loop.
544
566
// After all, there's nothing strictly "wrong" with unassigned type vars,
545
567
// it just fails TreeChecker's linting.
546
- maximizeType(mt.paramInfos( 0 ) , Spans .NoSpan )
568
+ maximizeType(unapplyArgType , Spans .NoSpan )
547
569
mt
548
570
}
549
571
0 commit comments