@@ -437,65 +437,82 @@ object ProtoTypes {
437
437
/** Approximate occurrences of parameter types and uninstantiated typevars
438
438
* by wildcard types.
439
439
*/
440
- final def wildApprox (tp : Type , theMap : WildApproxMap = null )(implicit ctx : Context ): Type = tp match {
440
+ final def wildApprox (tp : Type , theMap : WildApproxMap , seen : Set [ PolyParam ] )(implicit ctx : Context ): Type = tp match {
441
441
case tp : NamedType => // default case, inlined for speed
442
442
if (tp.symbol.isStatic) tp
443
- else tp.derivedSelect(wildApprox(tp.prefix, theMap))
443
+ else tp.derivedSelect(wildApprox(tp.prefix, theMap, seen ))
444
444
case tp : RefinedType => // default case, inlined for speed
445
- tp.derivedRefinedType(wildApprox(tp.parent, theMap), tp.refinedName, wildApprox(tp.refinedInfo, theMap))
445
+ tp.derivedRefinedType(
446
+ wildApprox(tp.parent, theMap, seen),
447
+ tp.refinedName,
448
+ wildApprox(tp.refinedInfo, theMap, seen))
446
449
case tp : TypeAlias => // default case, inlined for speed
447
- tp.derivedTypeAlias(wildApprox(tp.alias, theMap))
450
+ tp.derivedTypeAlias(wildApprox(tp.alias, theMap, seen ))
448
451
case tp @ PolyParam (poly, pnum) =>
449
- def unconstrainedApprox = WildcardType (wildApprox(poly.paramBounds(pnum)).bounds)
450
- if (ctx.mode.is(Mode .TypevarsMissContext ))
451
- unconstrainedApprox
452
- else
453
- ctx.typerState.constraint.entry(tp) match {
454
- case bounds : TypeBounds => wildApprox(WildcardType (bounds))
455
- case NoType => unconstrainedApprox
456
- case inst => wildApprox(inst)
457
- }
452
+ def wildApproxBounds (bounds : TypeBounds ) =
453
+ if (bounds.lo.isInstanceOf [NamedType ] && bounds.hi.isInstanceOf [NamedType ])
454
+ WildcardType (wildApprox(bounds, theMap, seen).bounds)
455
+ else if (seen.contains(tp)) WildcardType
456
+ else WildcardType (wildApprox(bounds, theMap, seen + tp).bounds)
457
+ def unconstrainedApprox = wildApproxBounds(poly.paramBounds(pnum))
458
+ def approxPoly =
459
+ if (ctx.mode.is(Mode .TypevarsMissContext )) unconstrainedApprox
460
+ else
461
+ ctx.typerState.constraint.entry(tp) match {
462
+ case bounds : TypeBounds => wildApproxBounds(bounds)
463
+ case NoType => unconstrainedApprox
464
+ case inst => wildApprox(inst, theMap, seen)
465
+ }
466
+ approxPoly
458
467
case MethodParam (mt, pnum) =>
459
- WildcardType (TypeBounds .upper(wildApprox(mt.paramTypes(pnum))))
468
+ WildcardType (TypeBounds .upper(wildApprox(mt.paramTypes(pnum), theMap, seen )))
460
469
case tp : TypeVar =>
461
- wildApprox(tp.underlying)
470
+ wildApprox(tp.underlying, theMap, seen )
462
471
case tp @ HKApply (tycon, args) =>
463
- wildApprox(tycon) match {
472
+ wildApprox(tycon, theMap, seen ) match {
464
473
case _ : WildcardType => WildcardType // this ensures we get a * type
465
- case tycon1 => tp.derivedAppliedType(tycon1, args.mapConserve(wildApprox(_)))
474
+ case tycon1 => tp.derivedAppliedType(tycon1, args.mapConserve(wildApprox(_, theMap, seen )))
466
475
}
467
476
case tp : AndType =>
468
- val tp1a = wildApprox(tp.tp1)
469
- val tp2a = wildApprox(tp.tp2)
470
- def wildBounds (tp : Type ) =
471
- if (tp.isInstanceOf [WildcardType ]) tp.bounds else TypeBounds .upper(tp)
472
- if (tp1a.isInstanceOf [WildcardType ] || tp2a.isInstanceOf [WildcardType ])
473
- WildcardType (wildBounds(tp1a) & wildBounds(tp2a))
474
- else
475
- tp.derivedAndType(tp1a, tp2a)
477
+ def approxAnd = {
478
+ val tp1a = wildApprox(tp.tp1, theMap, seen)
479
+ val tp2a = wildApprox(tp.tp2, theMap, seen)
480
+ def wildBounds (tp : Type ) =
481
+ if (tp.isInstanceOf [WildcardType ]) tp.bounds else TypeBounds .upper(tp)
482
+ if (tp1a.isInstanceOf [WildcardType ] || tp2a.isInstanceOf [WildcardType ])
483
+ WildcardType (wildBounds(tp1a) & wildBounds(tp2a))
484
+ else
485
+ tp.derivedAndType(tp1a, tp2a)
486
+ }
487
+ approxAnd
476
488
case tp : OrType =>
477
- val tp1a = wildApprox(tp.tp1)
478
- val tp2a = wildApprox(tp.tp2)
479
- if (tp1a.isInstanceOf [WildcardType ] || tp2a.isInstanceOf [WildcardType ])
480
- WildcardType (tp1a.bounds | tp2a.bounds)
481
- else
482
- tp.derivedOrType(tp1a, tp2a)
489
+ def approxOr = {
490
+ val tp1a = wildApprox(tp.tp1, theMap, seen)
491
+ val tp2a = wildApprox(tp.tp2, theMap, seen)
492
+ if (tp1a.isInstanceOf [WildcardType ] || tp2a.isInstanceOf [WildcardType ])
493
+ WildcardType (tp1a.bounds | tp2a.bounds)
494
+ else
495
+ tp.derivedOrType(tp1a, tp2a)
496
+ }
497
+ approxOr
483
498
case tp : LazyRef =>
484
499
WildcardType
485
500
case tp : SelectionProto =>
486
- tp.derivedSelectionProto(tp.name, wildApprox(tp.memberProto), NoViewsAllowed )
501
+ tp.derivedSelectionProto(tp.name, wildApprox(tp.memberProto, theMap, seen ), NoViewsAllowed )
487
502
case tp : ViewProto =>
488
- tp.derivedViewProto(wildApprox(tp.argType), wildApprox(tp.resultType))
503
+ tp.derivedViewProto(
504
+ wildApprox(tp.argType, theMap, seen),
505
+ wildApprox(tp.resultType, theMap, seen))
489
506
case _ : ThisType | _ : BoundType | NoPrefix => // default case, inlined for speed
490
507
tp
491
508
case _ =>
492
- (if (theMap != null ) theMap else new WildApproxMap ).mapOver(tp)
509
+ (if (theMap != null ) theMap else new WildApproxMap (seen) ).mapOver(tp)
493
510
}
494
511
495
512
@ sharable object AssignProto extends UncachedGroundType with MatchAlways
496
513
497
- private [ProtoTypes ] class WildApproxMap (implicit ctx : Context ) extends TypeMap {
498
- def apply (tp : Type ) = wildApprox(tp, this )
514
+ private [ProtoTypes ] class WildApproxMap (val seen : Set [ PolyParam ])( implicit ctx : Context ) extends TypeMap {
515
+ def apply (tp : Type ) = wildApprox(tp, this , seen )
499
516
}
500
517
501
518
/** Dummy tree to be used as an argument of a FunProto or ViewProto type */
0 commit comments