@@ -446,31 +446,38 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
446446 * inline annotations from their parameters. The generated `def` is appended
447447 * to `bindingsBuf`.
448448 * @param name the name of the parameter
449- * @param paramtp the type of the parameter
449+ * @param formal the type of the parameter
450450 * @param arg the argument corresponding to the parameter
451451 * @param bindingsBuf the buffer to which the definition should be appended
452452 */
453- private def paramBindingDef (name : Name , paramtp : Type , arg0 : Tree ,
453+ private def paramBindingDef (name : Name , formal : Type , arg0 : Tree ,
454454 bindingsBuf : mutable.ListBuffer [ValOrDefDef ])(using Context ): ValOrDefDef = {
455+ val isByName = formal.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 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
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 (formal)) // 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,33 @@ 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 ]], formalss : List [List [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(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
506516
507517 // Compute val-definitions for all this-proxies and append them to `bindingsBuf`
508518 private def computeThisBindings () = {
@@ -686,8 +696,16 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(using Context) {
686696 )
687697 }
688698
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+
689707 // 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
691709 return call
692710
693711 // make sure prefix is executed if it is impure
0 commit comments