@@ -383,17 +383,20 @@ object Inferencing {
383
383
def isSkolemFree (tp : Type )(using Context ): Boolean =
384
384
! tp.existsPart(_.isInstanceOf [SkolemType ])
385
385
386
- /** The list of uninstantiated type variables bound by some prefix of type `T` which
387
- * occur in at least one formal parameter type of a prefix application.
386
+ /** The list of uninstantiated type variables bound by some prefix of type `T` or
387
+ * by arguments of an application prefix, which occur at least once as a formal type parameter
388
+ * of an application either from a prefix or an argument of an application node.
388
389
* Considered prefixes are:
389
390
* - The function `f` of an application node `f(e1, .., en)`
390
391
* - The function `f` of a type application node `f[T1, ..., Tn]`
391
392
* - The prefix `p` of a selection `p.f`.
392
393
* - The result expression `e` of a block `{s1; .. sn; e}`.
393
394
*/
394
395
def tvarsInParams (tree : Tree , locked : TypeVars )(using Context ): List [TypeVar ] = {
395
- @ tailrec def boundVars (tree : Tree , acc : List [TypeVar ]): List [TypeVar ] = tree match {
396
- case Apply (fn, _) => boundVars(fn, acc)
396
+ def boundVars (tree : Tree , acc : List [TypeVar ]): List [TypeVar ] = tree match {
397
+ case Apply (fn, args) =>
398
+ val argTpVars = args.flatMap(boundVars(_, Nil ))
399
+ boundVars(fn, acc ++ argTpVars)
397
400
case TypeApply (fn, targs) =>
398
401
val tvars = targs.filter(_.isInstanceOf [InferredTypeTree ]).tpes.collect {
399
402
case tvar : TypeVar
@@ -406,16 +409,18 @@ object Inferencing {
406
409
case Block (_, expr) => boundVars(expr, acc)
407
410
case _ => acc
408
411
}
409
- @ tailrec def occurring (tree : Tree , toTest : List [TypeVar ], acc : List [TypeVar ]): List [TypeVar ] =
412
+ def occurring (tree : Tree , toTest : List [TypeVar ], acc : List [TypeVar ]): List [TypeVar ] =
410
413
if (toTest.isEmpty) acc
411
414
else tree match {
412
- case Apply (fn, _) =>
415
+ case Apply (fn, args) =>
416
+ val argsOcc = args.flatMap(occurring(_, toTest, Nil ))
417
+ val argsNocc = toTest.filterNot(argsOcc.contains)
413
418
fn.tpe.widen match {
414
419
case mtp : MethodType =>
415
- val (occ, nocc) = toTest .partition(tvar => mtp.paramInfos.exists(tvar.occursIn))
416
- occurring(fn, nocc, occ ::: acc)
420
+ val (occ, nocc) = argsNocc .partition(tvar => mtp.paramInfos.exists(tvar.occursIn))
421
+ occurring(fn, nocc, occ ::: argsOcc ::: acc)
417
422
case _ =>
418
- occurring(fn, toTest, acc)
423
+ occurring(fn, argsNocc, argsOcc ::: acc)
419
424
}
420
425
case TypeApply (fn, targs) => occurring(fn, toTest, acc)
421
426
case Select (pre, _) => occurring(pre, toTest, acc)
0 commit comments