// closure does the necessary substitions for a ClosureExpr n and returns the new
// closure node.
func (subst *inlsubst) closure(n *ir.ClosureExpr) ir.Node {
- // Prior to the subst edit, set a flag in the inlsubst to
- // indicated that we don't want to update the source positions in
- // the new closure. If we do this, it will appear that the closure
- // itself has things inlined into it, which is not the case. See
- // issue #46234 for more details.
+ // Prior to the subst edit, set a flag in the inlsubst to indicate
+ // that we don't want to update the source positions in the new
+ // closure function. If we do this, it will appear that the
+ // closure itself has things inlined into it, which is not the
+ // case. See issue #46234 for more details. At the same time, we
+ // do want to update the position in the new ClosureExpr (which is
+ // part of the function we're working on). See #49171 for an
+ // example of what happens if we miss that update.
+ newClosurePos := subst.updatedPos(n.Pos())
defer func(prev bool) { subst.noPosUpdate = prev }(subst.noPosUpdate)
subst.noPosUpdate = true
// Actually create the named function for the closure, now that
// the closure is inlined in a specific function.
newclo := newfn.OClosure
+ newclo.SetPos(newClosurePos)
newclo.SetInit(subst.list(n.Init()))
return typecheck.Expr(newclo)
}
return x + 2
}
y, sink = func() (func(int) int, int) { // ERROR "can inline main.func12"
- return func(x int) int { // ERROR "func literal does not escape" "can inline main.func12"
+ return func(x int) int { // ERROR "can inline main.func12"
return x + 1
}, 42
- }() // ERROR "inlining call to main.func12"
+ }() // ERROR "func literal does not escape" "inlining call to main.func12"
if y(40) != 41 {
ppanic("y(40) != 41")
}
return x + 2
}
y, sink = func() (func(int) int, int) { // ERROR "can inline main.func13.2"
- return func(x int) int { // ERROR "func literal does not escape" "can inline main.func13.2"
+ return func(x int) int { // ERROR "can inline main.func13.2"
return x + 1
}, 42
- }() // ERROR "inlining call to main.func13.2"
+ }() // ERROR "func literal does not escape" "inlining call to main.func13.2"
if y(40) != 41 {
ppanic("y(40) != 41")
}
foo := func() int { return 1 } // ERROR "can inline o.func1" "func literal does not escape"
func(x int) { // ERROR "can inline o.func2"
if x > 10 {
- foo = func() int { return 2 } // ERROR "func literal does not escape" "can inline o.func2"
+ foo = func() int { return 2 } // ERROR "can inline o.func2"
}
- }(11) // ERROR "inlining call to o.func2"
+ }(11) // ERROR "func literal does not escape" "inlining call to o.func2"
return foo()
}