@@ -659,17 +659,28 @@ object TypeOps:
659
659
*/
660
660
private def instantiateToSubType (tp1 : NamedType , tp2 : Type )(using Context ): Type = {
661
661
/** expose abstract type references to their bounds or tvars according to variance */
662
- class ApproximateTypeParams ( using Context ) extends TypeMap {
662
+ val approximateTypeParams = new TypeMap {
663
663
val boundTypeParams = util.HashMap [TypeRef , TypeVar ]()
664
664
665
665
def apply (tp : Type ): Type = tp.dealias match {
666
666
case _ : MatchType =>
667
667
tp // break cycles
668
668
669
669
case tp : TypeRef if ! tp.symbol.isClass =>
670
- def lo = apply(tp.underlying.loBound)
671
- def hi = apply(tp.underlying.hiBound)
672
- boundTypeParams.getOrElseUpdate(tp, newTypeVar(TypeBounds (lo, hi)))
670
+ def lo = LazyRef (apply(tp.underlying.loBound))
671
+ def hi = LazyRef (apply(tp.underlying.hiBound))
672
+ val lookup = boundTypeParams.lookup(tp)
673
+ if lookup != null then lookup
674
+ else
675
+ val tv = newTypeVar(TypeBounds (lo, hi))
676
+ boundTypeParams(tp) = tv
677
+ // Force lazy ref eagerly using current context
678
+ // Otherwise, the lazy ref will be forced with a unknown context,
679
+ // which causes a problem in tests/patmat/i3645e.scala
680
+ lo.ref
681
+ hi.ref
682
+ tv
683
+ end if
673
684
674
685
case AppliedType (tycon : TypeRef , _) if ! tycon.dealias.typeSymbol.isClass =>
675
686
// Type inference cannot handle X[Y] <:< Int
@@ -690,8 +701,6 @@ object TypeOps:
690
701
}
691
702
}
692
703
693
- def approximateTypeParams (tp : Type )(using Context ) = new ApproximateTypeParams ().apply(tp)
694
-
695
704
// Prefix inference, replace `p.C.this.Child` with `X.Child` where `X <: p.C`
696
705
// Note: we need to strip ThisType in `p` recursively.
697
706
//
0 commit comments