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  }