github.com/jhump/golang-x-tools@v0.0.0-20220218190644-4958d6d39439/go/analysis/passes/loopclosure/testdata/src/a/a.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file contains tests for the loopclosure checker. 6 7 package testdata 8 9 import "golang.org/x/sync/errgroup" 10 11 func _() { 12 var s []int 13 for i, v := range s { 14 go func() { 15 println(i) // want "loop variable i captured by func literal" 16 println(v) // want "loop variable v captured by func literal" 17 }() 18 } 19 for i, v := range s { 20 defer func() { 21 println(i) // want "loop variable i captured by func literal" 22 println(v) // want "loop variable v captured by func literal" 23 }() 24 } 25 for i := range s { 26 go func() { 27 println(i) // want "loop variable i captured by func literal" 28 }() 29 } 30 for _, v := range s { 31 go func() { 32 println(v) // want "loop variable v captured by func literal" 33 }() 34 } 35 for i, v := range s { 36 go func() { 37 println(i, v) 38 }() 39 println("unfortunately, we don't catch the error above because of this statement") 40 } 41 for i, v := range s { 42 go func(i, v int) { 43 println(i, v) 44 }(i, v) 45 } 46 for i, v := range s { 47 i, v := i, v 48 go func() { 49 println(i, v) 50 }() 51 } 52 // If the key of the range statement is not an identifier 53 // the code should not panic (it used to). 54 var x [2]int 55 var f int 56 for x[0], f = range s { 57 go func() { 58 _ = f // want "loop variable f captured by func literal" 59 }() 60 } 61 type T struct { 62 v int 63 } 64 for _, v := range s { 65 go func() { 66 _ = T{v: 1} 67 _ = map[int]int{v: 1} // want "loop variable v captured by func literal" 68 }() 69 } 70 71 // ordinary for-loops 72 for i := 0; i < 10; i++ { 73 go func() { 74 print(i) // want "loop variable i captured by func literal" 75 }() 76 } 77 for i, j := 0, 1; i < 100; i, j = j, i+j { 78 go func() { 79 print(j) // want "loop variable j captured by func literal" 80 }() 81 } 82 type cons struct { 83 car int 84 cdr *cons 85 } 86 var head *cons 87 for p := head; p != nil; p = p.cdr { 88 go func() { 89 print(p.car) // want "loop variable p captured by func literal" 90 }() 91 } 92 } 93 94 // Group is used to test that loopclosure does not match on any type named "Group". 95 // The checker only matches on methods "(*...errgroup.Group).Go". 96 type Group struct{}; 97 98 func (g *Group) Go(func() error) {} 99 100 func _() { 101 var s []int 102 // errgroup.Group.Go() invokes Go routines 103 g := new(errgroup.Group) 104 for i, v := range s { 105 g.Go(func() error { 106 print(i) // want "loop variable i captured by func literal" 107 print(v) // want "loop variable v captured by func literal" 108 return nil 109 }) 110 } 111 // Do not match other Group.Go cases 112 g1 := new(Group) 113 for i, v := range s { 114 g1.Go(func() error { 115 print(i) 116 print(v) 117 return nil 118 }) 119 } 120 }