@@ -73,10 +73,11 @@ object Checking {
73
73
showInferred(MissingTypeParameterInTypeApp (arg.tpe), app, tpt))
74
74
}
75
75
for (arg, which, bound) <- TypeOps .boundsViolations(args, boundss, instantiate, app) do
76
- report.error(
77
- showInferred(DoesNotConformToBound (arg.tpe, which, bound),
78
- app, tpt),
79
- arg.srcPos.focus)
76
+ if checkGoodBounds(arg.tpe, arg.srcPos.focus) then
77
+ report.error(
78
+ showInferred(DoesNotConformToBound (arg.tpe, which, bound),
79
+ app, tpt),
80
+ arg.srcPos.focus)
80
81
81
82
/** Check that type arguments `args` conform to corresponding bounds in `tl`
82
83
* Note: This does not check the bounds of AppliedTypeTrees. These
@@ -85,6 +86,18 @@ object Checking {
85
86
def checkBounds (args : List [tpd.Tree ], tl : TypeLambda )(using Context ): Unit =
86
87
checkBounds(args, tl.paramInfos, _.substParams(tl, _))
87
88
89
+ def checkGoodBounds (tpe : Type , pos : SrcPos )(using Context ): Boolean =
90
+ def recur (tp : Type ) = tp.dealias match
91
+ case tp : TypeRef =>
92
+ checkGoodBounds(tp.info, pos)
93
+ case TypeBounds (lo, hi) if ! (lo <:< hi) =>
94
+ val argStr = if tp eq tpe then " " else i " $tpe"
95
+ report.error(i " type argument $argStr has potentially unrealizable bounds $tp" , pos)
96
+ false
97
+ case _ =>
98
+ true
99
+ recur(tpe)
100
+
88
101
/** Check applied type trees for well-formedness. This means
89
102
* - all arguments are within their corresponding bounds
90
103
* - if type is a higher-kinded application with wildcard arguments,
0 commit comments