@@ -452,25 +452,32 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
452452 */
453453 private def paramBindingDef (name : Name , paramtp : Type , arg0 : Tree ,
454454 bindingsBuf : mutable.ListBuffer [ValOrDefDef ])(using Context ): ValOrDefDef = {
455+ val isByName = paramtp.dealias.isInstanceOf [ExprType ]
455456 val arg = arg0 match {
456457 case Typed (arg1, tpt) if tpt.tpe.isRepeatedParam && arg1.tpe.derivesFrom(defn.ArrayClass ) =>
457458 wrapArray(arg1, arg0.tpe.elemType)
458459 case _ => arg0
459460 }
460461 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
465+ else if isByName then ExprType (argtpe.widen)
466+ else argtpe.widen
467+ var bindingFlags : FlagSet = InlineProxy
468+ if paramtp.widenExpr.hasAnnotation(defn.InlineParamAnnot ) then
469+ bindingFlags |= Inline
470+ if isByName then
471+ bindingFlags |= Method
468472 val boundSym = newSym(InlineBinderName .fresh(name.asTermName), bindingFlags, bindingType).asTerm
469473 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 (paramtp)) // type ascribe RHS to avoid type errors in expansion. See i8612.scala
477+ if isByName then DefDef (boundSym, newArg)
472478 else ValDef (boundSym, newArg)
473479 }.withSpan(boundSym.span)
480+ inlining.println(i " parameter binding: $binding, $argIsBottom" )
474481 bindingsBuf += binding
475482 binding
476483 }
@@ -479,30 +486,35 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
479486 * corresponding arguments. `bindingbuf` will be further extended later by
480487 * proxies to this-references. Issue an error if some arguments are missing.
481488 */
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 ]], paramSubst : Type => Type ): Boolean =
491+ tp match
492+ case tp : PolyType =>
493+ tp.paramNames.lazyZip(targs).foreach { (name, arg) =>
495494 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
500496 }
501- computeParamBindings(tp.resultType, targs, argss.tail)
502- case _ =>
503- assert(targs.isEmpty)
504- assert(argss.isEmpty)
505- true
497+ computeParamBindings(
498+ tp.resultType, targs.drop(tp.paramNames.length), argss,
499+ paramSubst.andThen(_.substParams(tp, targs.map(_.tpe.stripTypeVar))))
500+ case tp : MethodType =>
501+ if argss.isEmpty then
502+ report.error(i " missing arguments for inline method $inlinedMethod" , call.srcPos)
503+ false
504+ else
505+ tp.paramNames.lazyZip(tp.paramInfos).lazyZip(argss.head).foreach { (name, paramtp, arg) =>
506+ paramSpan(name) = arg.span
507+ paramBinding(name) = arg.tpe.dealias match
508+ case _ : SingletonType if isIdempotentPath(arg) =>
509+ arg.tpe
510+ case _ =>
511+ paramBindingDef(name, paramSubst(paramtp), arg, bindingsBuf).symbol.termRef
512+ }
513+ computeParamBindings(tp.resultType, targs, argss.tail, paramSubst)
514+ case _ =>
515+ assert(targs.isEmpty)
516+ assert(argss.isEmpty)
517+ true
506518
507519 // Compute val-definitions for all this-proxies and append them to `bindingsBuf`
508520 private def computeThisBindings () = {
@@ -687,7 +699,7 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
687699 }
688700
689701 // Compute bindings for all parameters, appending them to bindingsBuf
690- if ! computeParamBindings(inlinedMethod.info, callTypeArgs, callValueArgss) then
702+ if ! computeParamBindings(inlinedMethod.info, callTypeArgs, callValueArgss, identity ) then
691703 return call
692704
693705 // make sure prefix is executed if it is impure
0 commit comments