@@ -452,24 +452,28 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
452
452
*/
453
453
private def paramBindingDef (name : Name , paramtp : Type , arg0 : Tree ,
454
454
bindingsBuf : mutable.ListBuffer [ValOrDefDef ])(using Context ): ValOrDefDef = {
455
+ val isByName = paramtp.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 paramtp.dealias
465
+ else if isByName then ExprType (argtpe.widen)
466
+ else argtpe
467
+ var bindingFlags : FlagSet = InlineProxy
468
+ if paramtp.widenExpr.hasAnnotation(defn.InlineParamAnnot ) && ! argIsBottom then
469
+ bindingFlags |= Inline // Don't inline arguments of type Nothing or Null; they need to be type ascribed
470
+ // to avoid type errors in the inlined code. See i8612.scala
471
+ if isByName then
472
+ bindingFlags |= Method
468
473
val boundSym = newSym(InlineBinderName .fresh(name.asTermName), bindingFlags, bindingType).asTerm
469
474
val binding = {
470
475
val newArg = arg.changeOwner(ctx.owner, boundSym)
471
- if (isByName) DefDef (boundSym, newArg)
472
- else ValDef (boundSym, newArg)
476
+ if isByName then DefDef (boundSym, newArg) else ValDef (boundSym, newArg)
473
477
}.withSpan(boundSym.span)
474
478
bindingsBuf += binding
475
479
binding
@@ -479,30 +483,35 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
479
483
* corresponding arguments. `bindingbuf` will be further extended later by
480
484
* proxies to this-references. Issue an error if some arguments are missing.
481
485
*/
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) =>
486
+ private def computeParamBindings (
487
+ tp : Type , targs : List [Tree ], argss : List [List [Tree ]], paramSubst : Type => Type ): Boolean =
488
+ tp match
489
+ case tp : PolyType =>
490
+ tp.paramNames.lazyZip(targs).foreach { (name, arg) =>
495
491
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
- }
492
+ paramBinding(name) = arg.tpe.stripTypeVar
500
493
}
501
- computeParamBindings(tp.resultType, targs, argss.tail)
502
- case _ =>
503
- assert(targs.isEmpty)
504
- assert(argss.isEmpty)
505
- true
494
+ computeParamBindings(
495
+ tp.resultType, targs.drop(tp.paramNames.length), argss,
496
+ paramSubst.andThen(_.substParams(tp, targs.map(_.tpe.stripTypeVar))))
497
+ case tp : MethodType =>
498
+ if argss.isEmpty then
499
+ report.error(i " missing arguments for inline method $inlinedMethod" , call.srcPos)
500
+ false
501
+ else
502
+ tp.paramNames.lazyZip(tp.paramInfos).lazyZip(argss.head).foreach { (name, paramtp, arg) =>
503
+ paramSpan(name) = arg.span
504
+ paramBinding(name) = arg.tpe.dealias match
505
+ case _ : SingletonType if isIdempotentPath(arg) =>
506
+ arg.tpe
507
+ case _ =>
508
+ paramBindingDef(name, paramSubst(paramtp), arg, bindingsBuf).symbol.termRef
509
+ }
510
+ computeParamBindings(tp.resultType, targs, argss.tail, paramSubst)
511
+ case _ =>
512
+ assert(targs.isEmpty)
513
+ assert(argss.isEmpty)
514
+ true
506
515
507
516
// Compute val-definitions for all this-proxies and append them to `bindingsBuf`
508
517
private def computeThisBindings () = {
@@ -687,7 +696,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
687
696
}
688
697
689
698
// Compute bindings for all parameters, appending them to bindingsBuf
690
- if ! computeParamBindings(inlinedMethod.info, callTypeArgs, callValueArgss) then
699
+ if ! computeParamBindings(inlinedMethod.info, callTypeArgs, callValueArgss, identity ) then
691
700
return call
692
701
693
702
// make sure prefix is executed if it is impure
0 commit comments