@@ -47,7 +47,7 @@ type Name struct {
47
47
Embed * []Embed // list of embedded files, for ONAME var
48
48
49
49
// For a local variable (not param) or extern, the initializing assignment (OAS or OAS2).
50
- // For a closure var, the ONAME node of the outer captured variable.
50
+ // For a closure var, the ONAME node of the original (outermost) captured variable.
51
51
// For the case-local variables of a type switch, the type switch guard (OTYPESW).
52
52
// For a range variable, the range statement (ORANGE)
53
53
// For a recv variable in a case of a select statement, the receive assignment (OSELRECV2)
@@ -59,77 +59,9 @@ type Name struct {
59
59
60
60
Heapaddr * Name // temp holding heap address of param
61
61
62
- // ONAME closure linkage
63
- // Consider:
64
- //
65
- // func f() {
66
- // x := 1 // x1
67
- // func() {
68
- // use(x) // x2
69
- // func() {
70
- // use(x) // x3
71
- // --- parser is here ---
72
- // }()
73
- // }()
74
- // }
75
- //
76
- // There is an original declaration of x and then a chain of mentions of x
77
- // leading into the current function. Each time x is mentioned in a new closure,
78
- // we create a variable representing x for use in that specific closure,
79
- // since the way you get to x is different in each closure.
80
- //
81
- // Let's number the specific variables as shown in the code:
82
- // x1 is the original x, x2 is when mentioned in the closure,
83
- // and x3 is when mentioned in the closure in the closure.
84
- //
85
- // We keep these linked (assume N > 1):
86
- //
87
- // - x1.Defn = original declaration statement for x (like most variables)
88
- // - x1.Innermost = current innermost closure x (in this case x3), or nil for none
89
- // - x1.IsClosureVar() = false
90
- //
91
- // - xN.Defn = x1, N > 1
92
- // - xN.IsClosureVar() = true, N > 1
93
- // - x2.Outer = nil
94
- // - xN.Outer = x(N-1), N > 2
95
- //
96
- //
97
- // When we look up x in the symbol table, we always get x1.
98
- // Then we can use x1.Innermost (if not nil) to get the x
99
- // for the innermost known closure function,
100
- // but the first reference in a closure will find either no x1.Innermost
101
- // or an x1.Innermost with .Funcdepth < Funcdepth.
102
- // In that case, a new xN must be created, linked in with:
103
- //
104
- // xN.Defn = x1
105
- // xN.Outer = x1.Innermost
106
- // x1.Innermost = xN
107
- //
108
- // When we finish the function, we'll process its closure variables
109
- // and find xN and pop it off the list using:
110
- //
111
- // x1 := xN.Defn
112
- // x1.Innermost = xN.Outer
113
- //
114
- // We leave x1.Innermost set so that we can still get to the original
115
- // variable quickly. Not shown here, but once we're
116
- // done parsing a function and no longer need xN.Outer for the
117
- // lexical x reference links as described above, funcLit
118
- // recomputes xN.Outer as the semantic x reference link tree,
119
- // even filling in x in intermediate closures that might not
120
- // have mentioned it along the way to inner closures that did.
121
- // See funcLit for details.
122
- //
123
- // During the eventual compilation, then, for closure variables we have:
124
- //
125
- // xN.Defn = original variable
126
- // xN.Outer = variable captured in next outward scope
127
- // to make closure where xN appears
128
- //
129
- // Because of the sharding of pieces of the node, x.Defn means x.Name.Defn
130
- // and x.Innermost/Outer means x.Name.Param.Innermost/Outer.
131
- Innermost * Name
132
- Outer * Name
62
+ // Outer points to the immediately enclosing function's copy of this
63
+ // closure variable. If not a closure variable, then Outer is nil.
64
+ Outer * Name
133
65
}
134
66
135
67
func (n * Name ) isExpr () {}
@@ -406,80 +338,6 @@ func NewHiddenParam(pos src.XPos, fn *Func, sym *types.Sym, typ *types.Type) *Na
406
338
return NewClosureVar (pos , fn , fake )
407
339
}
408
340
409
- // CaptureName returns a Name suitable for referring to n from within function
410
- // fn or from the package block if fn is nil. If n is a free variable declared
411
- // within a function that encloses fn, then CaptureName returns the closure
412
- // variable that refers to n within fn, creating it if necessary.
413
- // Otherwise, it simply returns n.
414
- func CaptureName (pos src.XPos , fn * Func , n * Name ) * Name {
415
- if n .Op () != ONAME || n .Curfn == nil {
416
- return n // okay to use directly
417
- }
418
- if n .IsClosureVar () {
419
- base .FatalfAt (pos , "misuse of CaptureName on closure variable: %v" , n )
420
- }
421
-
422
- c := n .Innermost
423
- if c == nil {
424
- c = n
425
- }
426
- if c .Curfn == fn {
427
- return c
428
- }
429
-
430
- if fn == nil {
431
- base .FatalfAt (pos , "package-block reference to %v, declared in %v" , n , n .Curfn )
432
- }
433
-
434
- // Do not have a closure var for the active closure yet; make one.
435
- c = NewClosureVar (pos , fn , c )
436
-
437
- // Link into list of active closure variables.
438
- // Popped from list in FinishCaptureNames.
439
- n .Innermost = c
440
-
441
- return c
442
- }
443
-
444
- // FinishCaptureNames handles any work leftover from calling CaptureName
445
- // earlier. outerfn should be the function that immediately encloses fn.
446
- func FinishCaptureNames (pos src.XPos , outerfn , fn * Func ) {
447
- // closure-specific variables are hanging off the
448
- // ordinary ones; see CaptureName above.
449
- // unhook them.
450
- // make the list of pointers for the closure call.
451
- for _ , cv := range fn .ClosureVars {
452
- // Unlink from n; see comment above on type Name for these fields.
453
- n := cv .Defn .(* Name )
454
- n .Innermost = cv .Outer
455
-
456
- // If the closure usage of n is not dense, we need to make it
457
- // dense by recapturing n within the enclosing function.
458
- //
459
- // That is, suppose we just finished parsing the innermost
460
- // closure f4 in this code:
461
- //
462
- // func f() {
463
- // n := 1
464
- // func() { // f2
465
- // use(n)
466
- // func() { // f3
467
- // func() { // f4
468
- // use(n)
469
- // }()
470
- // }()
471
- // }()
472
- // }
473
- //
474
- // At this point cv.Outer is f2's n; there is no n for f3. To
475
- // construct the closure f4 from within f3, we need to use f3's
476
- // n and in this case we need to create f3's n with CaptureName.
477
- //
478
- // We'll decide later in walk whether to use v directly or &v.
479
- cv .Outer = CaptureName (pos , outerfn , n )
480
- }
481
- }
482
-
483
341
// SameSource reports whether two nodes refer to the same source
484
342
// element.
485
343
//
0 commit comments