cvars := make([]*ir.Name, r.int64())
for i := range cvars {
cvars[i] = ir.CaptureName(r.pos(), fn, r.localName().Canonical())
+ if go117ExportTypes {
+ if cvars[i].Type() != nil || cvars[i].Defn == nil {
+ base.Fatalf("bad import of closure variable")
+ }
+ // Closure variable should have Defn set, which is its captured
+ // variable, and it gets the same type as the captured variable.
+ cvars[i].SetType(cvars[i].Defn.Type())
+ }
}
fn.ClosureVars = cvars
r.allClosureVars = append(r.allClosureVars, cvars...)
clo := ir.NewClosureExpr(pos, fn)
fn.OClosure = clo
+ if go117ExportTypes {
+ clo.SetType(typ)
+ }
return clo
y := func(x int) int { // ERROR "can inline main.func11" "func literal does not escape"
return x + 2
}
- y, sink = func() (func(int) int, int) { // ERROR "func literal does not escape"
- return func(x int) int { // ERROR "can inline main.func12" "func literal escapes"
+ y, sink = func() (func(int) int, int) { // ERROR "can inline main.func12"
+ return func(x int) int { // ERROR "can inline main.func12"
return x + 1
}, 42
- }()
+ }() // ERROR "func literal does not escape" "inlining call to main.func12"
if y(40) != 41 {
ppanic("y(40) != 41")
}
{
func() { // ERROR "func literal does not escape"
- y := func(x int) int { // ERROR "can inline main.func13.1" "func literal does not escape"
+ y := func(x int) int { // ERROR "func literal does not escape" "can inline main.func13.1"
return x + 2
}
- y, sink = func() (func(int) int, int) { // ERROR "func literal does not escape"
- return func(x int) int { // ERROR "can inline main.func13.2" "func literal escapes"
+ y, sink = func() (func(int) int, int) { // ERROR "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" "func literal does not escape"
if y(40) != 41 {
ppanic("y(40) != 41")
}
{
x := 42
- if z := func(y int) int { // ERROR "func literal does not escape"
- return func() int { // ERROR "can inline main.func22.1"
+ if z := func(y int) int { // ERROR "can inline main.func22"
+ return func() int { // ERROR "can inline main.func22.1" "can inline main.func30"
return x + y
}() // ERROR "inlining call to main.func22.1"
- }(1); z != 43 {
+ }(1); z != 43 { // ERROR "inlining call to main.func22" "inlining call to main.func30"
ppanic("z != 43")
}
- if z := func(y int) int { // ERROR "func literal does not escape"
- return func() int { // ERROR "can inline main.func23.1"
+ if z := func(y int) int { // ERROR "func literal does not escape" "can inline main.func23"
+ return func() int { // ERROR "can inline main.func23.1" "can inline main.func31"
return x + y
}() // ERROR "inlining call to main.func23.1"
- }; z(1) != 43 {
+ }; z(1) != 43 { // ERROR "inlining call to main.func23" "inlining call to main.func31"
ppanic("z(1) != 43")
}
}
{
a := 1
- func() { // ERROR "func literal does not escape"
- func() { // ERROR "can inline main.func24"
+ func() { // ERROR "can inline main.func24"
+ func() { // ERROR "can inline main.func24" "can inline main.func32"
a = 2
}() // ERROR "inlining call to main.func24"
- }()
+ }() // ERROR "inlining call to main.func24" "inlining call to main.func32"
if a != 2 {
ppanic("a != 2")
}
a := 2
if r := func(x int) int { // ERROR "func literal does not escape"
b := 3
- return func(y int) int { // ERROR "func literal does not escape"
+ return func(y int) int { // ERROR "can inline main.func27.1"
c := 5
- return func(z int) int { // ERROR "can inline main.func27.1.1"
+ return func(z int) int { // ERROR "can inline main.func27.1.1" "can inline main.func27.2"
return a*x + b*y + c*z
}(10) // ERROR "inlining call to main.func27.1.1"
- }(100)
+ }(100) // ERROR "inlining call to main.func27.1" "inlining call to main.func27.2"
}(1000); r != 2350 {
ppanic("r != 2350")
}
a := 2
if r := func(x int) int { // ERROR "func literal does not escape"
b := 3
- return func(y int) int { // ERROR "func literal does not escape"
+ return func(y int) int { // ERROR "can inline main.func28.1"
c := 5
- func(z int) { // ERROR "can inline main.func28.1.1"
+ func(z int) { // ERROR "can inline main.func28.1.1" "can inline main.func28.2"
a = a * x
b = b * y
c = c * z
}(10) // ERROR "inlining call to main.func28.1.1"
return a + c
- }(100) + b
+ }(100) + b // ERROR "inlining call to main.func28.1" "inlining call to main.func28.2"
}(1000); r != 2350 {
ppanic("r != 2350")
}
var somethingWrong error
// local closures can be inlined
-func l(x, y int) (int, int, error) {
+func l(x, y int) (int, int, error) { // ERROR "can inline l"
e := func(err error) (int, int, error) { // ERROR "can inline l.func1" "func literal does not escape" "leaking param: err to result"
return 0, 0, err
}
// make sure assignment inside closure is detected
func o() int {
foo := func() int { return 1 } // ERROR "can inline o.func1" "func literal does not escape"
- func(x int) { // ERROR "func literal does not escape"
+ func(x int) { // ERROR "can inline o.func2"
if x > 10 {
- foo = func() int { return 2 } // ERROR "can inline o.func2" "func literal escapes"
+ foo = func() int { return 2 } // ERROR "can inline o.func2"
}
- }(11)
+ }(11) // ERROR "func literal does not escape" "inlining call to o.func2"
return foo()
}
-func p() int {
+func p() int { // ERROR "can inline p"
return func() int { return 42 }() // ERROR "can inline p.func1" "inlining call to p.func1"
}
-func q(x int) int {
+func q(x int) int { // ERROR "can inline q"
foo := func() int { return x * 2 } // ERROR "can inline q.func1" "func literal does not escape"
return foo() // ERROR "inlining call to q.func1"
}
foo := func(x int) int { // ERROR "can inline r.func1" "func literal does not escape"
return x + z
}
- bar := func(x int) int { // ERROR "func literal does not escape"
- return x + func(y int) int { // ERROR "can inline r.func2.1"
+ bar := func(x int) int { // ERROR "func literal does not escape" "can inline r.func2"
+ return x + func(y int) int { // ERROR "can inline r.func2.1" "can inline r.func3"
return 2*y + x*z
}(x) // ERROR "inlining call to r.func2.1"
}
- return foo(42) + bar(42) // ERROR "inlining call to r.func1"
+ return foo(42) + bar(42) // ERROR "inlining call to r.func1" "inlining call to r.func2" "inlining call to r.func3"
}
-func s0(x int) int {
+func s0(x int) int { // ERROR "can inline s0"
foo := func() { // ERROR "can inline s0.func1" "func literal does not escape"
x = x + 1
}
return x
}
-func s1(x int) int {
+func s1(x int) int { // ERROR "can inline s1"
foo := func() int { // ERROR "can inline s1.func1" "func literal does not escape"
return x
}