@@ -446,31 +446,38 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
446
446
* inline annotations from their parameters. The generated `def` is appended
447
447
* to `bindingsBuf`.
448
448
* @param name the name of the parameter
449
- * @param paramtp the type of the parameter
449
+ * @param formal the type of the parameter
450
450
* @param arg the argument corresponding to the parameter
451
451
* @param bindingsBuf the buffer to which the definition should be appended
452
452
*/
453
- private def paramBindingDef (name : Name , paramtp : Type , arg0 : Tree ,
453
+ private def paramBindingDef (name : Name , formal : Type , arg0 : Tree ,
454
454
bindingsBuf : mutable.ListBuffer [ValOrDefDef ])(using Context ): ValOrDefDef = {
455
+ val isByName = formal.dealias.isInstanceOf [ExprType ]
455
456
val arg = arg0 match {
456
457
case Typed (arg1, tpt) if tpt.tpe.isRepeatedParam && arg1.tpe.derivesFrom(defn.ArrayClass ) =>
457
458
wrapArray(arg1, arg0.tpe.elemType)
458
459
case _ => arg0
459
460
}
460
461
val argtpe = arg.tpe.dealiasKeepAnnots.translateFromRepeated(toArray = false )
461
- val isByName = paramtp.dealias.isInstanceOf [ExprType ]
462
- var inlineFlags : FlagSet = InlineProxy
463
- if (paramtp.widenExpr.hasAnnotation(defn.InlineParamAnnot )) inlineFlags |= Inline
464
- if (isByName) inlineFlags |= Method
465
- val (bindingFlags, bindingType) =
466
- if (isByName) (inlineFlags, ExprType (argtpe.widen))
467
- else (inlineFlags, argtpe.widen)
462
+ val argIsBottom = argtpe.isBottomTypeAfterErasure
463
+ val bindingType =
464
+ if argIsBottom then formal
465
+ else if isByName then ExprType (argtpe.widen)
466
+ else argtpe.widen
467
+ var bindingFlags : FlagSet = InlineProxy
468
+ if formal.widenExpr.hasAnnotation(defn.InlineParamAnnot ) then
469
+ bindingFlags |= Inline
470
+ if isByName then
471
+ bindingFlags |= Method
468
472
val boundSym = newSym(InlineBinderName .fresh(name.asTermName), bindingFlags, bindingType).asTerm
469
473
val binding = {
470
- val newArg = arg.changeOwner(ctx.owner, boundSym)
471
- if (isByName) DefDef (boundSym, newArg)
474
+ var newArg = arg.changeOwner(ctx.owner, boundSym)
475
+ if bindingFlags.is(Inline ) && argIsBottom then
476
+ newArg = Typed (newArg, TypeTree (formal)) // type ascribe RHS to avoid type errors in expansion. See i8612.scala
477
+ if isByName then DefDef (boundSym, newArg)
472
478
else ValDef (boundSym, newArg)
473
479
}.withSpan(boundSym.span)
480
+ inlining.println(i " parameter binding: $binding, $argIsBottom" )
474
481
bindingsBuf += binding
475
482
binding
476
483
}
@@ -479,30 +486,33 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
479
486
* corresponding arguments. `bindingbuf` will be further extended later by
480
487
* proxies to this-references. Issue an error if some arguments are missing.
481
488
*/
482
- private def computeParamBindings (tp : Type , targs : List [Tree ], argss : List [List [Tree ]]): Boolean = tp match
483
- case tp : PolyType =>
484
- tp.paramNames.lazyZip(targs).foreach { (name, arg) =>
485
- paramSpan(name) = arg.span
486
- paramBinding(name) = arg.tpe.stripTypeVar
487
- }
488
- computeParamBindings(tp.resultType, targs.drop(tp.paramNames.length), argss)
489
- case tp : MethodType =>
490
- if argss.isEmpty then
491
- report.error(i " missing arguments for inline method $inlinedMethod" , call.srcPos)
492
- false
493
- else
494
- tp.paramNames.lazyZip(tp.paramInfos).lazyZip(argss.head).foreach { (name, paramtp, arg) =>
489
+ private def computeParamBindings (
490
+ tp : Type , targs : List [Tree ], argss : List [List [Tree ]], formalss : List [List [Type ]]): Boolean =
491
+ tp match
492
+ case tp : PolyType =>
493
+ tp.paramNames.lazyZip(targs).foreach { (name, arg) =>
495
494
paramSpan(name) = arg.span
496
- paramBinding(name) = arg.tpe.dealias match {
497
- case _ : SingletonType if isIdempotentPath(arg) => arg.tpe
498
- case _ => paramBindingDef(name, paramtp, arg, bindingsBuf).symbol.termRef
499
- }
495
+ paramBinding(name) = arg.tpe.stripTypeVar
500
496
}
501
- computeParamBindings(tp.resultType, targs, argss.tail)
502
- case _ =>
503
- assert(targs.isEmpty)
504
- assert(argss.isEmpty)
505
- true
497
+ computeParamBindings(tp.resultType, targs.drop(tp.paramNames.length), argss, formalss)
498
+ case tp : MethodType =>
499
+ if argss.isEmpty then
500
+ report.error(i " missing arguments for inline method $inlinedMethod" , call.srcPos)
501
+ false
502
+ else
503
+ tp.paramNames.lazyZip(formalss.head).lazyZip(argss.head).foreach { (name, formal, arg) =>
504
+ paramSpan(name) = arg.span
505
+ paramBinding(name) = arg.tpe.dealias match
506
+ case _ : SingletonType if isIdempotentPath(arg) =>
507
+ arg.tpe
508
+ case _ =>
509
+ paramBindingDef(name, formal, arg, bindingsBuf).symbol.termRef
510
+ }
511
+ computeParamBindings(tp.resultType, targs, argss.tail, formalss.tail)
512
+ case _ =>
513
+ assert(targs.isEmpty)
514
+ assert(argss.isEmpty)
515
+ true
506
516
507
517
// Compute val-definitions for all this-proxies and append them to `bindingsBuf`
508
518
private def computeThisBindings () = {
@@ -686,8 +696,16 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
686
696
)
687
697
}
688
698
699
+ def paramTypess (call : Tree , acc : List [List [Type ]]): List [List [Type ]] = call match
700
+ case Apply (fn, args) =>
701
+ fn.tpe.widen.match
702
+ case mt : MethodType => paramTypess(fn, mt.instantiateParamInfos(args.tpes) :: acc)
703
+ case _ => Nil
704
+ case TypeApply (fn, _) => paramTypess(fn, acc)
705
+ case _ => acc
706
+
689
707
// Compute bindings for all parameters, appending them to bindingsBuf
690
- if ! computeParamBindings(inlinedMethod.info, callTypeArgs, callValueArgss) then
708
+ if ! computeParamBindings(inlinedMethod.info, callTypeArgs, callValueArgss, paramTypess(call, Nil ) ) then
691
709
return call
692
710
693
711
// make sure prefix is executed if it is impure
0 commit comments