@@ -529,74 +529,79 @@ object TypeOps:
529529 val skolemizedArgTypes = skolemizeWildcardArgs(argTypes, app)
530530 val violations = new mutable.ListBuffer [BoundsViolation ]
531531
532- for ((arg, bounds) <- args zip boundss) {
533- def checkOverlapsBounds (lo : Type , hi : Type ): Unit = {
534- // println(i" = ${instantiate(bounds.hi, argTypes)}")
535-
536- var checkCtx = ctx // the context to be used for bounds checking
537- if (argTypes ne skolemizedArgTypes) { // some of the arguments are wildcards
538-
539- /** Is there a `LazyRef(TypeRef(_, sym))` reference in `tp`? */
540- def isLazyIn (sym : Symbol , tp : Type ): Boolean = {
541- def isReference (tp : Type ) = tp match {
542- case tp : LazyRef => tp.ref.isInstanceOf [TypeRef ] && tp.ref.typeSymbol == sym
543- case _ => false
544- }
545- tp.existsPart(isReference, forceLazy = false )
546- }
532+ def checkOverlapsBounds (lo : Type , hi : Type , arg : Tree , bounds : TypeBounds ): Unit = {
533+ // println(i" = ${instantiate(bounds.hi, argTypes)}")
547534
548- /** The argument types of the form `TypeRef(_, sym)` which appear as a LazyRef in `bounds`.
549- * This indicates that the application is used as an F-bound for the symbol referred to in the LazyRef.
550- */
551- val lazyRefs = skolemizedArgTypes collect {
552- case tp : TypeRef if isLazyIn(tp.symbol, bounds) => tp.symbol
553- }
535+ var checkCtx = ctx // the context to be used for bounds checking
536+ if (argTypes ne skolemizedArgTypes) { // some of the arguments are wildcards
554537
555- for (sym <- lazyRefs) {
556-
557- // If symbol `S` has an F-bound such as `C[?, S]` that contains wildcards,
558- // add a modifieed bound where wildcards are skolemized as a GADT bound for `S`.
559- // E.g. for `C[?, S]` we would add `C[C[?, S]#T0, S]` where `T0` is the first
560- // type parameter of `C`. The new bound is added as a GADT bound for `S` in
561- // `checkCtx`.
562- // This mirrors what we do for the bounds that are checked and allows us thus
563- // to bounds-check F-bounds with wildcards. A test case is pos/i6146.scala.
564-
565- def massage (tp : Type ): Type = tp match {
566- case tp @ AppliedType (tycon, args) =>
567- tp.derivedAppliedType(tycon, skolemizeWildcardArgs(args, tp))
568- case tp : AndOrType =>
569- tp.derivedAndOrType(massage(tp.tp1), massage(tp.tp2))
570- case _ => tp
571- }
572- def narrowBound (bound : Type , fromBelow : Boolean ): Unit = {
573- val bound1 = massage(bound)
574- if (bound1 ne bound) {
575- if (checkCtx eq ctx) checkCtx = ctx.fresh.setFreshGADTBounds
576- if (! checkCtx.gadt.contains(sym)) checkCtx.gadt.addToConstraint(sym)
577- checkCtx.gadt.addBound(sym, bound1, fromBelow)
578- typr.println(" install GADT bound $bound1 for when checking F-bounded $sym" )
579- }
580- }
581- narrowBound(sym.info.loBound, fromBelow = true )
582- narrowBound(sym.info.hiBound, fromBelow = false )
538+ /** Is there a `LazyRef(TypeRef(_, sym))` reference in `tp`? */
539+ def isLazyIn (sym : Symbol , tp : Type ): Boolean = {
540+ def isReference (tp : Type ) = tp match {
541+ case tp : LazyRef => tp.ref.isInstanceOf [TypeRef ] && tp.ref.typeSymbol == sym
542+ case _ => false
583543 }
544+ tp.existsPart(isReference, forceLazy = false )
584545 }
585546
586- val hiBound = instantiate(bounds.hi, skolemizedArgTypes)
587- val loBound = instantiate(bounds.lo, skolemizedArgTypes)
547+ /** The argument types of the form `TypeRef(_, sym)` which appear as a LazyRef in `bounds`.
548+ * This indicates that the application is used as an F-bound for the symbol referred to in the LazyRef.
549+ */
550+ val lazyRefs = skolemizedArgTypes collect {
551+ case tp : TypeRef if isLazyIn(tp.symbol, bounds) => tp.symbol
552+ }
588553
589- def check (using Context ) = {
590- if (! (lo <:< hiBound)) violations += ((arg, " upper" , hiBound))
591- if (! (loBound <:< hi)) violations += ((arg, " lower" , loBound))
554+ for (sym <- lazyRefs) {
555+
556+ // If symbol `S` has an F-bound such as `C[?, S]` that contains wildcards,
557+ // add a modifieed bound where wildcards are skolemized as a GADT bound for `S`.
558+ // E.g. for `C[?, S]` we would add `C[C[?, S]#T0, S]` where `T0` is the first
559+ // type parameter of `C`. The new bound is added as a GADT bound for `S` in
560+ // `checkCtx`.
561+ // This mirrors what we do for the bounds that are checked and allows us thus
562+ // to bounds-check F-bounds with wildcards. A test case is pos/i6146.scala.
563+
564+ def massage (tp : Type ): Type = tp match {
565+ case tp @ AppliedType (tycon, args) =>
566+ tp.derivedAppliedType(tycon, skolemizeWildcardArgs(args, tp))
567+ case tp : AndOrType =>
568+ tp.derivedAndOrType(massage(tp.tp1), massage(tp.tp2))
569+ case _ => tp
570+ }
571+ def narrowBound (bound : Type , fromBelow : Boolean ): Unit = {
572+ val bound1 = massage(bound)
573+ if (bound1 ne bound) {
574+ if (checkCtx eq ctx) checkCtx = ctx.fresh.setFreshGADTBounds
575+ if (! checkCtx.gadt.contains(sym)) checkCtx.gadt.addToConstraint(sym)
576+ checkCtx.gadt.addBound(sym, bound1, fromBelow)
577+ typr.println(" install GADT bound $bound1 for when checking F-bounded $sym" )
578+ }
579+ }
580+ narrowBound(sym.info.loBound, fromBelow = true )
581+ narrowBound(sym.info.hiBound, fromBelow = false )
592582 }
593- check(using checkCtx)
594583 }
595- arg.tpe match {
596- case TypeBounds (lo, hi) => checkOverlapsBounds(lo, hi)
597- case tp => checkOverlapsBounds(tp, tp)
584+ val hiBound = instantiate(bounds.hi, skolemizedArgTypes)
585+ val loBound = instantiate(bounds.lo, skolemizedArgTypes)
586+
587+ def check (using Context ) = {
588+ if (! (lo <:< hiBound)) violations += ((arg, " upper" , hiBound))
589+ if (! (loBound <:< hi)) violations += ((arg, " lower" , loBound))
598590 }
591+ check(using checkCtx)
599592 }
593+
594+ def loop (args : List [Tree ], boundss : List [TypeBounds ]): Unit = args match
595+ case arg :: args1 => boundss match
596+ case bounds :: boundss1 =>
597+ arg.tpe match
598+ case TypeBounds (lo, hi) => checkOverlapsBounds(lo, hi, arg, bounds)
599+ case tp => checkOverlapsBounds(tp, tp, arg, bounds)
600+ loop(args1, boundss1)
601+ case _ =>
602+ case _ =>
603+
604+ loop(args, boundss)
600605 violations.toList
601606 }
602607
0 commit comments