1// Copyright 2023 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/*
6Package rangefunc rewrites range-over-func to code that doesn't use range-over-funcs.
7Rewriting the construct in the front end, before noder, means the functions generated during
8the rewrite are available in a noder-generated representation for inlining by the back end.
9
10# Theory of Operation
11
12The basic idea is to rewrite
13
14	for x := range f {
15		...
16	}
17
18into
19
20	f(func(x T) bool {
21		...
22	})
23
24But it's not usually that easy.
25
26# Range variables
27
28For a range not using :=, the assigned variables cannot be function parameters
29in the generated body function. Instead, we allocate fake parameters and
30start the body with an assignment. For example:
31
32	for expr1, expr2 = range f {
33		...
34	}
35
36becomes
37
38	f(func(#p1 T1, #p2 T2) bool {
39		expr1, expr2 = #p1, #p2
40		...
41	})
42
43(All the generated variables have a # at the start to signal that they
44are internal variables when looking at the generated code in a
45debugger. Because variables have all been resolved to the specific
46objects they represent, there is no danger of using plain "p1" and
47colliding with a Go variable named "p1"; the # is just nice to have,
48not for correctness.)
49
50It can also happen that there are fewer range variables than function
51arguments, in which case we end up with something like
52
53	f(func(x T1, _ T2) bool {
54		...
55	})
56
57or
58
59	f(func(#p1 T1, #p2 T2, _ T3) bool {
60		expr1, expr2 = #p1, #p2
61		...
62	})
63
64# Return
65
66If the body contains a "break", that break turns into "return false",
67to tell f to stop. And if the body contains a "continue", that turns
68into "return true", to tell f to proceed with the next value.
69Those are the easy cases.
70
71If the body contains a return or a break/continue/goto L, then we need
72to rewrite that into code that breaks out of the loop and then
73triggers that control flow. In general we rewrite
74
75	for x := range f {
76		...
77	}
78
79into
80
81	{
82		var #next int
83		f(func(x T1) bool {
84			...
85			return true
86		})
87		... check #next ...
88	}
89
90The variable #next is an integer code that says what to do when f
91returns. Each difficult statement sets #next and then returns false to
92stop f.
93
94A plain "return" rewrites to {#next = -1; return false}.
95The return false breaks the loop. Then when f returns, the "check
96#next" section includes
97
98	if #next == -1 { return }
99
100which causes the return we want.
101
102Return with arguments is more involved, and has to deal with
103corner cases involving panic, defer, and recover.  The results
104of the enclosing function or closure are rewritten to give them
105names if they don't have them already, and the names are assigned
106at the return site.
107
108	  func foo() (#rv1 A, #rv2 B) {
109
110		{
111			var (
112				#next int
113			)
114			f(func(x T1) bool {
115				...
116				{
117					// return a, b
118					#rv1, #rv2 = a, b
119					#next = -1
120					return false
121				}
122				...
123				return true
124			})
125			if #next == -1 { return }
126		}
127
128# Checking
129
130To permit checking that an iterator is well-behaved -- that is, that
131it does not call the loop body again after it has returned false or
132after the entire loop has exited (it might retain a copy of the body
133function, or pass it to another goroutine) -- each generated loop has
134its own #stateK variable that is used to check for permitted call
135patterns to the yield function for a loop body.
136
137The state values are:
138
139abi.RF_DONE = 0      // body of loop has exited in a non-panic way
140abi.RF_READY = 1     // body of loop has not exited yet, is not running
141abi.RF_PANIC = 2     // body of loop is either currently running, or has panicked
142abi.RF_EXHAUSTED = 3 // iterator function call, e.g. f(func(x t){...}), returned so the sequence is "exhausted".
143
144abi.RF_MISSING_PANIC = 4 // used to report errors.
145
146The value of #stateK transitions
147(1) before calling the iterator function,
148
149	var #stateN = abi.RF_READY
150
151(2) after the iterator function call returns,
152
153	if #stateN == abi.RF_PANIC {
154		panic(runtime.panicrangestate(abi.RF_MISSING_PANIC))
155	}
156	#stateN = abi.RF_EXHAUSTED
157
158(3) at the beginning of the iteration of the loop body,
159
160	if #stateN != abi.RF_READY { runtime.panicrangestate(#stateN) }
161	#stateN = abi.RF_PANIC
162
163(4) when loop iteration continues,
164
165	#stateN = abi.RF_READY
166	[return true]
167
168(5) when control flow exits the loop body.
169
170	#stateN = abi.RF_DONE
171	[return false]
172
173For example:
174
175	for x := range f {
176		...
177		if ... { break }
178		...
179	}
180
181becomes
182
183		{
184			var #state1 = abi.RF_READY
185			f(func(x T1) bool {
186				if #state1 != abi.RF_READY { runtime.panicrangestate(#state1) }
187				#state1 = abi.RF_PANIC
188				...
189				if ... { #state1 = abi.RF_DONE ; return false }
190				...
191				#state1 = abi.RF_READY
192				return true
193			})
194	        if #state1 == abi.RF_PANIC {
195	        	// the code for the loop body did not return normally
196	        	panic(runtime.panicrangestate(abi.RF_MISSING_PANIC))
197	        }
198			#state1 = abi.RF_EXHAUSTED
199		}
200
201# Nested Loops
202
203So far we've only considered a single loop. If a function contains a
204sequence of loops, each can be translated individually. But loops can
205be nested. It would work to translate the innermost loop and then
206translate the loop around it, and so on, except that there'd be a lot
207of rewriting of rewritten code and the overall traversals could end up
208taking time quadratic in the depth of the nesting. To avoid all that,
209we use a single rewriting pass that handles a top-most range-over-func
210loop and all the range-over-func loops it contains at the same time.
211
212If we need to return from inside a doubly-nested loop, the rewrites
213above stay the same, but the check after the inner loop only says
214
215	if #next < 0 { return false }
216
217to stop the outer loop so it can do the actual return. That is,
218
219	for range f {
220		for range g {
221			...
222			return a, b
223			...
224		}
225	}
226
227becomes
228
229	{
230		var (
231			#next int
232		)
233		var #state1 = abi.RF_READY
234		f(func() bool {
235			if #state1 != abi.RF_READY { runtime.panicrangestate(#state1) }
236			#state1 = abi.RF_PANIC
237			var #state2 = abi.RF_READY
238			g(func() bool {
239				if #state2 != abi.RF_READY { runtime.panicrangestate(#state2) }
240				...
241				{
242					// return a, b
243					#rv1, #rv2 = a, b
244					#next = -1
245					#state2 = abi.RF_DONE
246					return false
247				}
248				...
249				#state2 = abi.RF_READY
250				return true
251			})
252	        if #state2 == abi.RF_PANIC {
253	        	panic(runtime.panicrangestate(abi.RF_MISSING_PANIC))
254	        }
255			#state2 = abi.RF_EXHAUSTED
256			if #next < 0 {
257				#state1 = abi.RF_DONE
258				return false
259			}
260			#state1 = abi.RF_READY
261			return true
262		})
263	    if #state1 == abi.RF_PANIC {
264	       	panic(runtime.panicrangestate(abi.RF_MISSING_PANIC))
265	    }
266		#state1 = abi.RF_EXHAUSTED
267		if #next == -1 {
268			return
269		}
270	}
271
272# Labeled break/continue of range-over-func loops
273
274For a labeled break or continue of an outer range-over-func, we
275use positive #next values.
276
277Any such labeled break or continue
278really means "do N breaks" or "do N breaks and 1 continue".
279
280The positive #next value tells which level of loop N to target
281with a break or continue, where perLoopStep*N means break out of
282level N and perLoopStep*N-1 means continue into level N.  The
283outermost loop has level 1, therefore #next == perLoopStep means
284to break from the outermost loop, and #next == perLoopStep-1 means
285to continue the outermost loop.
286
287Loops that might need to propagate a labeled break or continue
288add one or both of these to the #next checks:
289
290	    // N == depth of this loop, one less than the one just exited.
291		if #next != 0 {
292		  if #next >= perLoopStep*N-1 { // break or continue this loop
293		  	if #next >= perLoopStep*N+1 { // error checking
294		  	   // TODO reason about what exactly can appear
295		  	   // here given full  or partial checking.
296	           runtime.panicrangestate(abi.RF_DONE)
297		  	}
298		  	rv := #next & 1 == 1 // code generates into #next&1
299			#next = 0
300			return rv
301		  }
302		  return false // or handle returns and gotos
303		}
304
305For example (with perLoopStep == 2)
306
307	F: for range f { // 1, 2
308		for range g { // 3, 4
309			for range h {
310				...
311				break F
312				...
313				...
314				continue F
315				...
316			}
317		}
318		...
319	}
320
321becomes
322
323	{
324		var #next int
325		var #state1 = abi.RF_READY
326		f(func() { // 1,2
327			if #state1 != abi.RF_READY { runtime.panicrangestate(#state1) }
328			#state1 = abi.RF_PANIC
329			var #state2 = abi.RF_READY
330			g(func() { // 3,4
331				if #state2 != abi.RF_READY { runtime.panicrangestate(#state2) }
332				#state2 = abi.RF_PANIC
333				var #state3 = abi.RF_READY
334				h(func() { // 5,6
335					if #state3 != abi.RF_READY { runtime.panicrangestate(#state3) }
336					#state3 = abi.RF_PANIC
337					...
338					{
339						// break F
340						#next = 2
341						#state3 = abi.RF_DONE
342						return false
343					}
344					...
345					{
346						// continue F
347						#next = 1
348						#state3 = abi.RF_DONE
349						return false
350					}
351					...
352					#state3 = abi.RF_READY
353					return true
354				})
355				if #state3 == abi.RF_PANIC {
356					panic(runtime.panicrangestate(abi.RF_MISSING_PANIC))
357				}
358				#state3 = abi.RF_EXHAUSTED
359				if #next != 0 {
360					// no breaks or continues targeting this loop
361					#state2 = abi.RF_DONE
362					return false
363				}
364				return true
365			})
366	    	if #state2 == abi.RF_PANIC {
367	       		panic(runtime.panicrangestate(abi.RF_MISSING_PANIC))
368	   		}
369			#state2 = abi.RF_EXHAUSTED
370			if #next != 0 { // just exited g, test for break/continue applied to f/F
371				if #next >= 1 {
372					if #next >= 3 { runtime.panicrangestate(abi.RF_DONE) } // error
373					rv := #next&1 == 1
374					#next = 0
375					return rv
376				}
377				#state1 = abi.RF_DONE
378				return false
379			}
380			...
381			return true
382		})
383	    if #state1 == abi.RF_PANIC {
384	       	panic(runtime.panicrangestate(abi.RF_MISSING_PANIC))
385	    }
386		#state1 = abi.RF_EXHAUSTED
387	}
388
389Note that the post-h checks only consider a break,
390since no generated code tries to continue g.
391
392# Gotos and other labeled break/continue
393
394The final control flow translations are goto and break/continue of a
395non-range-over-func statement. In both cases, we may need to break
396out of one or more range-over-func loops before we can do the actual
397control flow statement. Each such break/continue/goto L statement is
398assigned a unique negative #next value (since -1 is return). Then
399the post-checks for a given loop test for the specific codes that
400refer to labels directly targetable from that block. Otherwise, the
401generic
402
403	if #next < 0 { return false }
404
405check handles stopping the next loop to get one step closer to the label.
406
407For example
408
409	Top: print("start\n")
410	for range f {
411		for range g {
412			...
413			for range h {
414				...
415				goto Top
416				...
417			}
418		}
419	}
420
421becomes
422
423	Top: print("start\n")
424	{
425		var #next int
426		var #state1 = abi.RF_READY
427		f(func() {
428			if #state1 != abi.RF_READY{ runtime.panicrangestate(#state1) }
429			#state1 = abi.RF_PANIC
430			var #state2 = abi.RF_READY
431			g(func() {
432				if #state2 != abi.RF_READY { runtime.panicrangestate(#state2) }
433				#state2 = abi.RF_PANIC
434				...
435				var #state3 bool = abi.RF_READY
436				h(func() {
437					if #state3 != abi.RF_READY { runtime.panicrangestate(#state3) }
438					#state3 = abi.RF_PANIC
439					...
440					{
441						// goto Top
442						#next = -3
443						#state3 = abi.RF_DONE
444						return false
445					}
446					...
447					#state3 = abi.RF_READY
448					return true
449				})
450				if #state3 == abi.RF_PANIC {runtime.panicrangestate(abi.RF_MISSING_PANIC)}
451				#state3 = abi.RF_EXHAUSTED
452				if #next < 0 {
453					#state2 = abi.RF_DONE
454					return false
455				}
456				#state2 = abi.RF_READY
457				return true
458			})
459			if #state2 == abi.RF_PANIC {runtime.panicrangestate(abi.RF_MISSING_PANIC)}
460			#state2 = abi.RF_EXHAUSTED
461			if #next < 0 {
462				#state1 = abi.RF_DONE
463				return false
464			}
465			#state1 = abi.RF_READY
466			return true
467		})
468		if #state1 == abi.RF_PANIC {runtime.panicrangestate(abi.RF_MISSING_PANIC)}
469		#state1 = abi.RF_EXHAUSTED
470		if #next == -3 {
471			#next = 0
472			goto Top
473		}
474	}
475
476Labeled break/continue to non-range-over-funcs are handled the same
477way as goto.
478
479# Defers
480
481The last wrinkle is handling defer statements. If we have
482
483	for range f {
484		defer print("A")
485	}
486
487we cannot rewrite that into
488
489	f(func() {
490		defer print("A")
491	})
492
493because the deferred code will run at the end of the iteration, not
494the end of the containing function. To fix that, the runtime provides
495a special hook that lets us obtain a defer "token" representing the
496outer function and then use it in a later defer to attach the deferred
497code to that outer function.
498
499Normally,
500
501	defer print("A")
502
503compiles to
504
505	runtime.deferproc(func() { print("A") })
506
507This changes in a range-over-func. For example:
508
509	for range f {
510		defer print("A")
511	}
512
513compiles to
514
515	var #defers = runtime.deferrangefunc()
516	f(func() {
517		runtime.deferprocat(func() { print("A") }, #defers)
518	})
519
520For this rewriting phase, we insert the explicit initialization of
521#defers and then attach the #defers variable to the CallStmt
522representing the defer. That variable will be propagated to the
523backend and will cause the backend to compile the defer using
524deferprocat instead of an ordinary deferproc.
525
526TODO: Could call runtime.deferrangefuncend after f.
527*/
528package rangefunc
529
530import (
531	"cmd/compile/internal/base"
532	"cmd/compile/internal/syntax"
533	"cmd/compile/internal/types2"
534	"fmt"
535	"go/constant"
536	"internal/abi"
537	"os"
538)
539
540// nopos is the zero syntax.Pos.
541var nopos syntax.Pos
542
543// A rewriter implements rewriting the range-over-funcs in a given function.
544type rewriter struct {
545	pkg   *types2.Package
546	info  *types2.Info
547	sig   *types2.Signature
548	outer *syntax.FuncType
549	body  *syntax.BlockStmt
550
551	// References to important types and values.
552	any   types2.Object
553	bool  types2.Object
554	int   types2.Object
555	true  types2.Object
556	false types2.Object
557
558	// Branch numbering, computed as needed.
559	branchNext map[branch]int             // branch -> #next value
560	labelLoop  map[string]*syntax.ForStmt // label -> innermost rangefunc loop it is declared inside (nil for no loop)
561
562	// Stack of nodes being visited.
563	stack    []syntax.Node // all nodes
564	forStack []*forLoop    // range-over-func loops
565
566	rewritten map[*syntax.ForStmt]syntax.Stmt
567
568	// Declared variables in generated code for outermost loop.
569	declStmt         *syntax.DeclStmt
570	nextVar          types2.Object
571	defers           types2.Object
572	stateVarCount    int // stateVars are referenced from their respective loops
573	bodyClosureCount int // to help the debugger, the closures generated for loop bodies get names
574
575	rangefuncBodyClosures map[*syntax.FuncLit]bool
576}
577
578// A branch is a single labeled branch.
579type branch struct {
580	tok   syntax.Token
581	label string
582}
583
584// A forLoop describes a single range-over-func loop being processed.
585type forLoop struct {
586	nfor         *syntax.ForStmt // actual syntax
587	stateVar     *types2.Var     // #state variable for this loop
588	stateVarDecl *syntax.VarDecl
589	depth        int // outermost loop has depth 1, otherwise depth = depth(parent)+1
590
591	checkRet      bool     // add check for "return" after loop
592	checkBreak    bool     // add check for "break" after loop
593	checkContinue bool     // add check for "continue" after loop
594	checkBranch   []branch // add check for labeled branch after loop
595}
596
597type State int
598
599// Rewrite rewrites all the range-over-funcs in the files.
600// It returns the set of function literals generated from rangefunc loop bodies.
601// This allows for rangefunc loop bodies to be distingushed by debuggers.
602func Rewrite(pkg *types2.Package, info *types2.Info, files []*syntax.File) map[*syntax.FuncLit]bool {
603	ri := make(map[*syntax.FuncLit]bool)
604	for _, file := range files {
605		syntax.Inspect(file, func(n syntax.Node) bool {
606			switch n := n.(type) {
607			case *syntax.FuncDecl:
608				sig, _ := info.Defs[n.Name].Type().(*types2.Signature)
609				rewriteFunc(pkg, info, n.Type, n.Body, sig, ri)
610				return false
611			case *syntax.FuncLit:
612				sig, _ := info.Types[n].Type.(*types2.Signature)
613				if sig == nil {
614					tv := n.GetTypeInfo()
615					sig = tv.Type.(*types2.Signature)
616				}
617				rewriteFunc(pkg, info, n.Type, n.Body, sig, ri)
618				return false
619			}
620			return true
621		})
622	}
623	return ri
624}
625
626// rewriteFunc rewrites all the range-over-funcs in a single function (a top-level func or a func literal).
627// The typ and body are the function's type and body.
628func rewriteFunc(pkg *types2.Package, info *types2.Info, typ *syntax.FuncType, body *syntax.BlockStmt, sig *types2.Signature, ri map[*syntax.FuncLit]bool) {
629	if body == nil {
630		return
631	}
632	r := &rewriter{
633		pkg:                   pkg,
634		info:                  info,
635		outer:                 typ,
636		body:                  body,
637		sig:                   sig,
638		rangefuncBodyClosures: ri,
639	}
640	syntax.Inspect(body, r.inspect)
641	if (base.Flag.W != 0) && r.forStack != nil {
642		syntax.Fdump(os.Stderr, body)
643	}
644}
645
646// checkFuncMisuse reports whether to check for misuse of iterator callbacks functions.
647func (r *rewriter) checkFuncMisuse() bool {
648	return base.Debug.RangeFuncCheck != 0
649}
650
651// inspect is a callback for syntax.Inspect that drives the actual rewriting.
652// If it sees a func literal, it kicks off a separate rewrite for that literal.
653// Otherwise, it maintains a stack of range-over-func loops and
654// converts each in turn.
655func (r *rewriter) inspect(n syntax.Node) bool {
656	switch n := n.(type) {
657	case *syntax.FuncLit:
658		sig, _ := r.info.Types[n].Type.(*types2.Signature)
659		if sig == nil {
660			tv := n.GetTypeInfo()
661			sig = tv.Type.(*types2.Signature)
662		}
663		rewriteFunc(r.pkg, r.info, n.Type, n.Body, sig, r.rangefuncBodyClosures)
664		return false
665
666	default:
667		// Push n onto stack.
668		r.stack = append(r.stack, n)
669		if nfor, ok := forRangeFunc(n); ok {
670			loop := &forLoop{nfor: nfor, depth: 1 + len(r.forStack)}
671			r.forStack = append(r.forStack, loop)
672			r.startLoop(loop)
673		}
674
675	case nil:
676		// n == nil signals that we are done visiting
677		// the top-of-stack node's children. Find it.
678		n = r.stack[len(r.stack)-1]
679
680		// If we are inside a range-over-func,
681		// take this moment to replace any break/continue/goto/return
682		// statements directly contained in this node.
683		// Also replace any converted for statements
684		// with the rewritten block.
685		switch n := n.(type) {
686		case *syntax.BlockStmt:
687			for i, s := range n.List {
688				n.List[i] = r.editStmt(s)
689			}
690		case *syntax.CaseClause:
691			for i, s := range n.Body {
692				n.Body[i] = r.editStmt(s)
693			}
694		case *syntax.CommClause:
695			for i, s := range n.Body {
696				n.Body[i] = r.editStmt(s)
697			}
698		case *syntax.LabeledStmt:
699			n.Stmt = r.editStmt(n.Stmt)
700		}
701
702		// Pop n.
703		if len(r.forStack) > 0 && r.stack[len(r.stack)-1] == r.forStack[len(r.forStack)-1].nfor {
704			r.endLoop(r.forStack[len(r.forStack)-1])
705			r.forStack = r.forStack[:len(r.forStack)-1]
706		}
707		r.stack = r.stack[:len(r.stack)-1]
708	}
709	return true
710}
711
712// startLoop sets up for converting a range-over-func loop.
713func (r *rewriter) startLoop(loop *forLoop) {
714	// For first loop in function, allocate syntax for any, bool, int, true, and false.
715	if r.any == nil {
716		r.any = types2.Universe.Lookup("any")
717		r.bool = types2.Universe.Lookup("bool")
718		r.int = types2.Universe.Lookup("int")
719		r.true = types2.Universe.Lookup("true")
720		r.false = types2.Universe.Lookup("false")
721		r.rewritten = make(map[*syntax.ForStmt]syntax.Stmt)
722	}
723	if r.checkFuncMisuse() {
724		// declare the state flag for this loop's body
725		loop.stateVar, loop.stateVarDecl = r.stateVar(loop.nfor.Pos())
726	}
727}
728
729// editStmt returns the replacement for the statement x,
730// or x itself if it should be left alone.
731// This includes the for loops we are converting,
732// as left in x.rewritten by r.endLoop.
733func (r *rewriter) editStmt(x syntax.Stmt) syntax.Stmt {
734	if x, ok := x.(*syntax.ForStmt); ok {
735		if s := r.rewritten[x]; s != nil {
736			return s
737		}
738	}
739
740	if len(r.forStack) > 0 {
741		switch x := x.(type) {
742		case *syntax.BranchStmt:
743			return r.editBranch(x)
744		case *syntax.CallStmt:
745			if x.Tok == syntax.Defer {
746				return r.editDefer(x)
747			}
748		case *syntax.ReturnStmt:
749			return r.editReturn(x)
750		}
751	}
752
753	return x
754}
755
756// editDefer returns the replacement for the defer statement x.
757// See the "Defers" section in the package doc comment above for more context.
758func (r *rewriter) editDefer(x *syntax.CallStmt) syntax.Stmt {
759	if r.defers == nil {
760		// Declare and initialize the #defers token.
761		init := &syntax.CallExpr{
762			Fun: runtimeSym(r.info, "deferrangefunc"),
763		}
764		tv := syntax.TypeAndValue{Type: r.any.Type()}
765		tv.SetIsValue()
766		init.SetTypeInfo(tv)
767		r.defers = r.declOuterVar("#defers", r.any.Type(), init)
768	}
769
770	// Attach the token as an "extra" argument to the defer.
771	x.DeferAt = r.useObj(r.defers)
772	setPos(x.DeferAt, x.Pos())
773	return x
774}
775
776func (r *rewriter) stateVar(pos syntax.Pos) (*types2.Var, *syntax.VarDecl) {
777	r.stateVarCount++
778
779	name := fmt.Sprintf("#state%d", r.stateVarCount)
780	typ := r.int.Type()
781	obj := types2.NewVar(pos, r.pkg, name, typ)
782	n := syntax.NewName(pos, name)
783	setValueType(n, typ)
784	r.info.Defs[n] = obj
785
786	return obj, &syntax.VarDecl{NameList: []*syntax.Name{n}, Values: r.stateConst(abi.RF_READY)}
787}
788
789// editReturn returns the replacement for the return statement x.
790// See the "Return" section in the package doc comment above for more context.
791func (r *rewriter) editReturn(x *syntax.ReturnStmt) syntax.Stmt {
792	bl := &syntax.BlockStmt{}
793
794	if x.Results != nil {
795		// rewrite "return val" into "assign to named result; return"
796		if len(r.outer.ResultList) > 0 {
797			// Make sure that result parameters all have names
798			for i, a := range r.outer.ResultList {
799				if a.Name == nil || a.Name.Value == "_" {
800					r.generateParamName(r.outer.ResultList, i) // updates a.Name
801				}
802			}
803		}
804		// Assign to named results
805		results := []types2.Object{}
806		for _, a := range r.outer.ResultList {
807			results = append(results, r.info.Defs[a.Name])
808		}
809		bl.List = append(bl.List, &syntax.AssignStmt{Lhs: r.useList(results), Rhs: x.Results})
810		x.Results = nil
811	}
812
813	next := -1 // return
814
815	// Tell the loops along the way to check for a return.
816	for _, loop := range r.forStack {
817		loop.checkRet = true
818	}
819
820	// Set #next, and return false.
821
822	bl.List = append(bl.List, &syntax.AssignStmt{Lhs: r.next(), Rhs: r.intConst(next)})
823	if r.checkFuncMisuse() {
824		// mark this loop as exited, the others (which will be exited if iterators do not interfere) have not, yet.
825		bl.List = append(bl.List, r.setState(abi.RF_DONE, x.Pos()))
826	}
827	bl.List = append(bl.List, &syntax.ReturnStmt{Results: r.useObj(r.false)})
828	setPos(bl, x.Pos())
829	return bl
830}
831
832// perLoopStep is part of the encoding of loop-spanning control flow
833// for function range iterators.  Each multiple of two encodes a "return false"
834// passing control to an enclosing iterator; a terminal value of 1 encodes
835// "return true" (i.e., local continue) from the body function, and a terminal
836// value of 0 encodes executing the remainder of the body function.
837const perLoopStep = 2
838
839// editBranch returns the replacement for the branch statement x,
840// or x itself if it should be left alone.
841// See the package doc comment above for more context.
842func (r *rewriter) editBranch(x *syntax.BranchStmt) syntax.Stmt {
843	if x.Tok == syntax.Fallthrough {
844		// Fallthrough is unaffected by the rewrite.
845		return x
846	}
847
848	// Find target of break/continue/goto in r.forStack.
849	// (The target may not be in r.forStack at all.)
850	targ := x.Target
851	i := len(r.forStack) - 1
852	if x.Label == nil && r.forStack[i].nfor != targ {
853		// Unlabeled break or continue that's not nfor must be inside nfor. Leave alone.
854		return x
855	}
856	for i >= 0 && r.forStack[i].nfor != targ {
857		i--
858	}
859	// exitFrom is the index of the loop interior to the target of the control flow,
860	// if such a loop exists (it does not if i == len(r.forStack) - 1)
861	exitFrom := i + 1
862
863	// Compute the value to assign to #next and the specific return to use.
864	var next int
865	var ret *syntax.ReturnStmt
866	if x.Tok == syntax.Goto || i < 0 {
867		// goto Label
868		// or break/continue of labeled non-range-over-func loop (x.Label != nil).
869		// We may be able to leave it alone, or we may have to break
870		// out of one or more nested loops and then use #next to signal
871		// to complete the break/continue/goto.
872		// Figure out which range-over-func loop contains the label.
873		r.computeBranchNext()
874		nfor := r.forStack[len(r.forStack)-1].nfor
875		label := x.Label.Value
876		targ := r.labelLoop[label]
877		if nfor == targ {
878			// Label is in the innermost range-over-func loop; use it directly.
879			return x
880		}
881
882		// Set #next to the code meaning break/continue/goto label.
883		next = r.branchNext[branch{x.Tok, label}]
884
885		// Break out of nested loops up to targ.
886		i := len(r.forStack) - 1
887		for i >= 0 && r.forStack[i].nfor != targ {
888			i--
889		}
890		exitFrom = i + 1
891
892		// Mark loop we exit to get to targ to check for that branch.
893		// When i==-1 / exitFrom == 0 that's the outermost func body.
894		top := r.forStack[exitFrom]
895		top.checkBranch = append(top.checkBranch, branch{x.Tok, label})
896
897		// Mark loops along the way to check for a plain return, so they break.
898		for j := exitFrom + 1; j < len(r.forStack); j++ {
899			r.forStack[j].checkRet = true
900		}
901
902		// In the innermost loop, use a plain "return false".
903		ret = &syntax.ReturnStmt{Results: r.useObj(r.false)}
904	} else {
905		// break/continue of labeled range-over-func loop.
906		if exitFrom == len(r.forStack) {
907			// Simple break or continue.
908			// Continue returns true, break returns false, optionally both adjust state,
909			// neither modifies #next.
910			var state abi.RF_State
911			if x.Tok == syntax.Continue {
912				ret = &syntax.ReturnStmt{Results: r.useObj(r.true)}
913				state = abi.RF_READY
914			} else {
915				ret = &syntax.ReturnStmt{Results: r.useObj(r.false)}
916				state = abi.RF_DONE
917			}
918			var stmts []syntax.Stmt
919			if r.checkFuncMisuse() {
920				stmts = []syntax.Stmt{r.setState(state, x.Pos()), ret}
921			} else {
922				stmts = []syntax.Stmt{ret}
923			}
924			bl := &syntax.BlockStmt{
925				List: stmts,
926			}
927			setPos(bl, x.Pos())
928			return bl
929		}
930
931		ret = &syntax.ReturnStmt{Results: r.useObj(r.false)}
932
933		// The loop inside the one we are break/continue-ing
934		// needs to make that happen when we break out of it.
935		if x.Tok == syntax.Continue {
936			r.forStack[exitFrom].checkContinue = true
937		} else {
938			exitFrom = i // exitFrom--
939			r.forStack[exitFrom].checkBreak = true
940		}
941
942		// The loops along the way just need to break.
943		for j := exitFrom + 1; j < len(r.forStack); j++ {
944			r.forStack[j].checkBreak = true
945		}
946
947		// Set next to break the appropriate number of times;
948		// the final time may be a continue, not a break.
949		next = perLoopStep * (i + 1)
950		if x.Tok == syntax.Continue {
951			next--
952		}
953	}
954
955	// Assign #next = next and do the return.
956	as := &syntax.AssignStmt{Lhs: r.next(), Rhs: r.intConst(next)}
957	bl := &syntax.BlockStmt{
958		List: []syntax.Stmt{as},
959	}
960
961	if r.checkFuncMisuse() {
962		// Set #stateK for this loop.
963		// The exterior loops have not exited yet, and the iterator might interfere.
964		bl.List = append(bl.List, r.setState(abi.RF_DONE, x.Pos()))
965	}
966
967	bl.List = append(bl.List, ret)
968	setPos(bl, x.Pos())
969	return bl
970}
971
972// computeBranchNext computes the branchNext numbering
973// and determines which labels end up inside which range-over-func loop bodies.
974func (r *rewriter) computeBranchNext() {
975	if r.labelLoop != nil {
976		return
977	}
978
979	r.labelLoop = make(map[string]*syntax.ForStmt)
980	r.branchNext = make(map[branch]int)
981
982	var labels []string
983	var stack []syntax.Node
984	var forStack []*syntax.ForStmt
985	forStack = append(forStack, nil)
986	syntax.Inspect(r.body, func(n syntax.Node) bool {
987		if n != nil {
988			stack = append(stack, n)
989			if nfor, ok := forRangeFunc(n); ok {
990				forStack = append(forStack, nfor)
991			}
992			if n, ok := n.(*syntax.LabeledStmt); ok {
993				l := n.Label.Value
994				labels = append(labels, l)
995				f := forStack[len(forStack)-1]
996				r.labelLoop[l] = f
997			}
998		} else {
999			n := stack[len(stack)-1]
1000			stack = stack[:len(stack)-1]
1001			if n == forStack[len(forStack)-1] {
1002				forStack = forStack[:len(forStack)-1]
1003			}
1004		}
1005		return true
1006	})
1007
1008	// Assign numbers to all the labels we observed.
1009	used := -1 // returns use -1
1010	for _, l := range labels {
1011		used -= 3
1012		r.branchNext[branch{syntax.Break, l}] = used
1013		r.branchNext[branch{syntax.Continue, l}] = used + 1
1014		r.branchNext[branch{syntax.Goto, l}] = used + 2
1015	}
1016}
1017
1018// endLoop finishes the conversion of a range-over-func loop.
1019// We have inspected and rewritten the body of the loop and can now
1020// construct the body function and rewrite the for loop into a call
1021// bracketed by any declarations and checks it requires.
1022func (r *rewriter) endLoop(loop *forLoop) {
1023	// Pick apart for range X { ... }
1024	nfor := loop.nfor
1025	start, end := nfor.Pos(), nfor.Body.Rbrace // start, end position of for loop
1026	rclause := nfor.Init.(*syntax.RangeClause)
1027	rfunc := types2.CoreType(rclause.X.GetTypeInfo().Type).(*types2.Signature) // type of X - func(func(...)bool)
1028	if rfunc.Params().Len() != 1 {
1029		base.Fatalf("invalid typecheck of range func")
1030	}
1031	ftyp := types2.CoreType(rfunc.Params().At(0).Type()).(*types2.Signature) // func(...) bool
1032	if ftyp.Results().Len() != 1 {
1033		base.Fatalf("invalid typecheck of range func")
1034	}
1035
1036	// Give the closure generated for the body a name, to help the debugger connect it to its frame, if active.
1037	r.bodyClosureCount++
1038	clo := r.bodyFunc(nfor.Body.List, syntax.UnpackListExpr(rclause.Lhs), rclause.Def, ftyp, start, end)
1039	cloDecl, cloVar := r.declSingleVar(fmt.Sprintf("#yield%d", r.bodyClosureCount), clo.GetTypeInfo().Type, clo)
1040	setPos(cloDecl, start)
1041
1042	// Build X(bodyFunc)
1043	call := &syntax.ExprStmt{
1044		X: &syntax.CallExpr{
1045			Fun: rclause.X,
1046			ArgList: []syntax.Expr{
1047				r.useObj(cloVar),
1048			},
1049		},
1050	}
1051	setPos(call, start)
1052
1053	// Build checks based on #next after X(bodyFunc)
1054	checks := r.checks(loop, end)
1055
1056	// Rewrite for vars := range X { ... } to
1057	//
1058	//	{
1059	//		r.declStmt
1060	//		call
1061	//		checks
1062	//	}
1063	//
1064	// The r.declStmt can be added to by this loop or any inner loop
1065	// during the creation of r.bodyFunc; it is only emitted in the outermost
1066	// converted range loop.
1067	block := &syntax.BlockStmt{Rbrace: end}
1068	setPos(block, start)
1069	if len(r.forStack) == 1 && r.declStmt != nil {
1070		setPos(r.declStmt, start)
1071		block.List = append(block.List, r.declStmt)
1072	}
1073
1074	// declare the state variable here so it has proper scope and initialization
1075	if r.checkFuncMisuse() {
1076		stateVarDecl := &syntax.DeclStmt{DeclList: []syntax.Decl{loop.stateVarDecl}}
1077		setPos(stateVarDecl, start)
1078		block.List = append(block.List, stateVarDecl)
1079	}
1080
1081	// iteratorFunc(bodyFunc)
1082	block.List = append(block.List, cloDecl, call)
1083
1084	if r.checkFuncMisuse() {
1085		// iteratorFunc has exited, check for swallowed panic, and set body state to abi.RF_EXHAUSTED
1086		nif := &syntax.IfStmt{
1087			Cond: r.cond(syntax.Eql, r.useObj(loop.stateVar), r.stateConst(abi.RF_PANIC)),
1088			Then: &syntax.BlockStmt{
1089				List: []syntax.Stmt{r.callPanic(start, r.stateConst(abi.RF_MISSING_PANIC))},
1090			},
1091		}
1092		setPos(nif, end)
1093		block.List = append(block.List, nif)
1094		block.List = append(block.List, r.setState(abi.RF_EXHAUSTED, end))
1095	}
1096	block.List = append(block.List, checks...)
1097
1098	if len(r.forStack) == 1 { // ending an outermost loop
1099		r.declStmt = nil
1100		r.nextVar = nil
1101		r.defers = nil
1102	}
1103
1104	r.rewritten[nfor] = block
1105}
1106
1107func (r *rewriter) cond(op syntax.Operator, x, y syntax.Expr) *syntax.Operation {
1108	cond := &syntax.Operation{Op: op, X: x, Y: y}
1109	tv := syntax.TypeAndValue{Type: r.bool.Type()}
1110	tv.SetIsValue()
1111	cond.SetTypeInfo(tv)
1112	return cond
1113}
1114
1115func (r *rewriter) setState(val abi.RF_State, pos syntax.Pos) *syntax.AssignStmt {
1116	ss := r.setStateAt(len(r.forStack)-1, val)
1117	setPos(ss, pos)
1118	return ss
1119}
1120
1121func (r *rewriter) setStateAt(index int, stateVal abi.RF_State) *syntax.AssignStmt {
1122	loop := r.forStack[index]
1123	return &syntax.AssignStmt{
1124		Lhs: r.useObj(loop.stateVar),
1125		Rhs: r.stateConst(stateVal),
1126	}
1127}
1128
1129// bodyFunc converts the loop body (control flow has already been updated)
1130// to a func literal that can be passed to the range function.
1131//
1132// vars is the range variables from the range statement.
1133// def indicates whether this is a := range statement.
1134// ftyp is the type of the function we are creating
1135// start and end are the syntax positions to use for new nodes
1136// that should be at the start or end of the loop.
1137func (r *rewriter) bodyFunc(body []syntax.Stmt, lhs []syntax.Expr, def bool, ftyp *types2.Signature, start, end syntax.Pos) *syntax.FuncLit {
1138	// Starting X(bodyFunc); build up bodyFunc first.
1139	var params, results []*types2.Var
1140	results = append(results, types2.NewVar(start, nil, "#r", r.bool.Type()))
1141	bodyFunc := &syntax.FuncLit{
1142		// Note: Type is ignored but needs to be non-nil to avoid panic in syntax.Inspect.
1143		Type: &syntax.FuncType{},
1144		Body: &syntax.BlockStmt{
1145			List:   []syntax.Stmt{},
1146			Rbrace: end,
1147		},
1148	}
1149	r.rangefuncBodyClosures[bodyFunc] = true
1150	setPos(bodyFunc, start)
1151
1152	for i := 0; i < ftyp.Params().Len(); i++ {
1153		typ := ftyp.Params().At(i).Type()
1154		var paramVar *types2.Var
1155		if i < len(lhs) && def {
1156			// Reuse range variable as parameter.
1157			x := lhs[i]
1158			paramVar = r.info.Defs[x.(*syntax.Name)].(*types2.Var)
1159		} else {
1160			// Declare new parameter and assign it to range expression.
1161			paramVar = types2.NewVar(start, r.pkg, fmt.Sprintf("#p%d", 1+i), typ)
1162			if i < len(lhs) {
1163				x := lhs[i]
1164				as := &syntax.AssignStmt{Lhs: x, Rhs: r.useObj(paramVar)}
1165				as.SetPos(x.Pos())
1166				setPos(as.Rhs, x.Pos())
1167				bodyFunc.Body.List = append(bodyFunc.Body.List, as)
1168			}
1169		}
1170		params = append(params, paramVar)
1171	}
1172
1173	tv := syntax.TypeAndValue{
1174		Type: types2.NewSignatureType(nil, nil, nil,
1175			types2.NewTuple(params...),
1176			types2.NewTuple(results...),
1177			false),
1178	}
1179	tv.SetIsValue()
1180	bodyFunc.SetTypeInfo(tv)
1181
1182	loop := r.forStack[len(r.forStack)-1]
1183
1184	if r.checkFuncMisuse() {
1185		bodyFunc.Body.List = append(bodyFunc.Body.List, r.assertReady(start, loop))
1186		bodyFunc.Body.List = append(bodyFunc.Body.List, r.setState(abi.RF_PANIC, start))
1187	}
1188
1189	// Original loop body (already rewritten by editStmt during inspect).
1190	bodyFunc.Body.List = append(bodyFunc.Body.List, body...)
1191
1192	// end of loop body, set state to abi.RF_READY and return true to continue iteration
1193	if r.checkFuncMisuse() {
1194		bodyFunc.Body.List = append(bodyFunc.Body.List, r.setState(abi.RF_READY, end))
1195	}
1196	ret := &syntax.ReturnStmt{Results: r.useObj(r.true)}
1197	ret.SetPos(end)
1198	bodyFunc.Body.List = append(bodyFunc.Body.List, ret)
1199
1200	return bodyFunc
1201}
1202
1203// checks returns the post-call checks that need to be done for the given loop.
1204func (r *rewriter) checks(loop *forLoop, pos syntax.Pos) []syntax.Stmt {
1205	var list []syntax.Stmt
1206	if len(loop.checkBranch) > 0 {
1207		did := make(map[branch]bool)
1208		for _, br := range loop.checkBranch {
1209			if did[br] {
1210				continue
1211			}
1212			did[br] = true
1213			doBranch := &syntax.BranchStmt{Tok: br.tok, Label: &syntax.Name{Value: br.label}}
1214			list = append(list, r.ifNext(syntax.Eql, r.branchNext[br], true, doBranch))
1215		}
1216	}
1217
1218	curLoop := loop.depth - 1
1219	curLoopIndex := curLoop - 1
1220
1221	if len(r.forStack) == 1 {
1222		if loop.checkRet {
1223			list = append(list, r.ifNext(syntax.Eql, -1, false, retStmt(nil)))
1224		}
1225	} else {
1226
1227		// Idealized check, implemented more simply for now.
1228
1229		//	// N == depth of this loop, one less than the one just exited.
1230		//	if #next != 0 {
1231		//		if #next >= perLoopStep*N-1 { // this loop
1232		//			if #next >= perLoopStep*N+1 { // error checking
1233		//      		runtime.panicrangestate(abi.RF_DONE)
1234		//   		}
1235		//			rv := #next & 1 == 1 // code generates into #next&1
1236		//			#next = 0
1237		//			return rv
1238		//		}
1239		// 		return false // or handle returns and gotos
1240		//	}
1241
1242		if loop.checkRet {
1243			// Note: next < 0 also handles gotos handled by outer loops.
1244			// We set checkRet in that case to trigger this check.
1245			if r.checkFuncMisuse() {
1246				list = append(list, r.ifNext(syntax.Lss, 0, false, r.setStateAt(curLoopIndex, abi.RF_DONE), retStmt(r.useObj(r.false))))
1247			} else {
1248				list = append(list, r.ifNext(syntax.Lss, 0, false, retStmt(r.useObj(r.false))))
1249			}
1250		}
1251
1252		depthStep := perLoopStep * (curLoop)
1253
1254		if r.checkFuncMisuse() {
1255			list = append(list, r.ifNext(syntax.Gtr, depthStep, false, r.callPanic(pos, r.stateConst(abi.RF_DONE))))
1256		} else {
1257			list = append(list, r.ifNext(syntax.Gtr, depthStep, true))
1258		}
1259
1260		if r.checkFuncMisuse() {
1261			if loop.checkContinue {
1262				list = append(list, r.ifNext(syntax.Eql, depthStep-1, true, r.setStateAt(curLoopIndex, abi.RF_READY), retStmt(r.useObj(r.true))))
1263			}
1264
1265			if loop.checkBreak {
1266				list = append(list, r.ifNext(syntax.Eql, depthStep, true, r.setStateAt(curLoopIndex, abi.RF_DONE), retStmt(r.useObj(r.false))))
1267			}
1268
1269			if loop.checkContinue || loop.checkBreak {
1270				list = append(list, r.ifNext(syntax.Gtr, 0, false, r.setStateAt(curLoopIndex, abi.RF_DONE), retStmt(r.useObj(r.false))))
1271			}
1272
1273		} else {
1274			if loop.checkContinue {
1275				list = append(list, r.ifNext(syntax.Eql, depthStep-1, true, retStmt(r.useObj(r.true))))
1276			}
1277			if loop.checkBreak {
1278				list = append(list, r.ifNext(syntax.Eql, depthStep, true, retStmt(r.useObj(r.false))))
1279			}
1280			if loop.checkContinue || loop.checkBreak {
1281				list = append(list, r.ifNext(syntax.Gtr, 0, false, retStmt(r.useObj(r.false))))
1282			}
1283		}
1284	}
1285
1286	for _, j := range list {
1287		setPos(j, pos)
1288	}
1289	return list
1290}
1291
1292// retStmt returns a return statement returning the given return values.
1293func retStmt(results syntax.Expr) *syntax.ReturnStmt {
1294	return &syntax.ReturnStmt{Results: results}
1295}
1296
1297// ifNext returns the statement:
1298//
1299//	if #next op c { [#next = 0;] thens... }
1300func (r *rewriter) ifNext(op syntax.Operator, c int, zeroNext bool, thens ...syntax.Stmt) syntax.Stmt {
1301	var thenList []syntax.Stmt
1302	if zeroNext {
1303		clr := &syntax.AssignStmt{
1304			Lhs: r.next(),
1305			Rhs: r.intConst(0),
1306		}
1307		thenList = append(thenList, clr)
1308	}
1309	for _, then := range thens {
1310		thenList = append(thenList, then)
1311	}
1312	nif := &syntax.IfStmt{
1313		Cond: r.cond(op, r.next(), r.intConst(c)),
1314		Then: &syntax.BlockStmt{
1315			List: thenList,
1316		},
1317	}
1318	return nif
1319}
1320
1321// setValueType marks x as a value with type typ.
1322func setValueType(x syntax.Expr, typ syntax.Type) {
1323	tv := syntax.TypeAndValue{Type: typ}
1324	tv.SetIsValue()
1325	x.SetTypeInfo(tv)
1326}
1327
1328// assertReady returns the statement:
1329//
1330//	if #stateK != abi.RF_READY { runtime.panicrangestate(#stateK) }
1331//
1332// where #stateK is the state variable for loop.
1333func (r *rewriter) assertReady(start syntax.Pos, loop *forLoop) syntax.Stmt {
1334	nif := &syntax.IfStmt{
1335		Cond: r.cond(syntax.Neq, r.useObj(loop.stateVar), r.stateConst(abi.RF_READY)),
1336		Then: &syntax.BlockStmt{
1337			List: []syntax.Stmt{r.callPanic(start, r.useObj(loop.stateVar))},
1338		},
1339	}
1340	setPos(nif, start)
1341	return nif
1342}
1343
1344func (r *rewriter) callPanic(start syntax.Pos, arg syntax.Expr) syntax.Stmt {
1345	callPanicExpr := &syntax.CallExpr{
1346		Fun:     runtimeSym(r.info, "panicrangestate"),
1347		ArgList: []syntax.Expr{arg},
1348	}
1349	setValueType(callPanicExpr, nil) // no result type
1350	return &syntax.ExprStmt{X: callPanicExpr}
1351}
1352
1353// next returns a reference to the #next variable.
1354func (r *rewriter) next() *syntax.Name {
1355	if r.nextVar == nil {
1356		r.nextVar = r.declOuterVar("#next", r.int.Type(), nil)
1357	}
1358	return r.useObj(r.nextVar)
1359}
1360
1361// forRangeFunc checks whether n is a range-over-func.
1362// If so, it returns n.(*syntax.ForStmt), true.
1363// Otherwise it returns nil, false.
1364func forRangeFunc(n syntax.Node) (*syntax.ForStmt, bool) {
1365	nfor, ok := n.(*syntax.ForStmt)
1366	if !ok {
1367		return nil, false
1368	}
1369	nrange, ok := nfor.Init.(*syntax.RangeClause)
1370	if !ok {
1371		return nil, false
1372	}
1373	_, ok = types2.CoreType(nrange.X.GetTypeInfo().Type).(*types2.Signature)
1374	if !ok {
1375		return nil, false
1376	}
1377	return nfor, true
1378}
1379
1380// intConst returns syntax for an integer literal with the given value.
1381func (r *rewriter) intConst(c int) *syntax.BasicLit {
1382	lit := &syntax.BasicLit{
1383		Value: fmt.Sprint(c),
1384		Kind:  syntax.IntLit,
1385	}
1386	tv := syntax.TypeAndValue{Type: r.int.Type(), Value: constant.MakeInt64(int64(c))}
1387	tv.SetIsValue()
1388	lit.SetTypeInfo(tv)
1389	return lit
1390}
1391
1392func (r *rewriter) stateConst(s abi.RF_State) *syntax.BasicLit {
1393	return r.intConst(int(s))
1394}
1395
1396// useObj returns syntax for a reference to decl, which should be its declaration.
1397func (r *rewriter) useObj(obj types2.Object) *syntax.Name {
1398	n := syntax.NewName(nopos, obj.Name())
1399	tv := syntax.TypeAndValue{Type: obj.Type()}
1400	tv.SetIsValue()
1401	n.SetTypeInfo(tv)
1402	r.info.Uses[n] = obj
1403	return n
1404}
1405
1406// useList is useVar for a list of decls.
1407func (r *rewriter) useList(vars []types2.Object) syntax.Expr {
1408	var new []syntax.Expr
1409	for _, obj := range vars {
1410		new = append(new, r.useObj(obj))
1411	}
1412	if len(new) == 1 {
1413		return new[0]
1414	}
1415	return &syntax.ListExpr{ElemList: new}
1416}
1417
1418func (r *rewriter) makeVarName(pos syntax.Pos, name string, typ types2.Type) (*types2.Var, *syntax.Name) {
1419	obj := types2.NewVar(pos, r.pkg, name, typ)
1420	n := syntax.NewName(pos, name)
1421	tv := syntax.TypeAndValue{Type: typ}
1422	tv.SetIsValue()
1423	n.SetTypeInfo(tv)
1424	r.info.Defs[n] = obj
1425	return obj, n
1426}
1427
1428func (r *rewriter) generateParamName(results []*syntax.Field, i int) {
1429	obj, n := r.sig.RenameResult(results, i)
1430	r.info.Defs[n] = obj
1431}
1432
1433// declOuterVar declares a variable with a given name, type, and initializer value,
1434// in the same scope as the outermost loop in a loop nest.
1435func (r *rewriter) declOuterVar(name string, typ types2.Type, init syntax.Expr) *types2.Var {
1436	if r.declStmt == nil {
1437		r.declStmt = &syntax.DeclStmt{}
1438	}
1439	stmt := r.declStmt
1440	obj, n := r.makeVarName(stmt.Pos(), name, typ)
1441	stmt.DeclList = append(stmt.DeclList, &syntax.VarDecl{
1442		NameList: []*syntax.Name{n},
1443		// Note: Type is ignored
1444		Values: init,
1445	})
1446	return obj
1447}
1448
1449// declSingleVar declares a variable with a given name, type, and initializer value,
1450// and returns both the declaration and variable, so that the declaration can be placed
1451// in a specific scope.
1452func (r *rewriter) declSingleVar(name string, typ types2.Type, init syntax.Expr) (*syntax.DeclStmt, *types2.Var) {
1453	stmt := &syntax.DeclStmt{}
1454	obj, n := r.makeVarName(stmt.Pos(), name, typ)
1455	stmt.DeclList = append(stmt.DeclList, &syntax.VarDecl{
1456		NameList: []*syntax.Name{n},
1457		// Note: Type is ignored
1458		Values: init,
1459	})
1460	return stmt, obj
1461}
1462
1463// runtimePkg is a fake runtime package that contains what we need to refer to in package runtime.
1464var runtimePkg = func() *types2.Package {
1465	var nopos syntax.Pos
1466	pkg := types2.NewPackage("runtime", "runtime")
1467	anyType := types2.Universe.Lookup("any").Type()
1468	intType := types2.Universe.Lookup("int").Type()
1469
1470	// func deferrangefunc() unsafe.Pointer
1471	obj := types2.NewFunc(nopos, pkg, "deferrangefunc", types2.NewSignatureType(nil, nil, nil, nil, types2.NewTuple(types2.NewParam(nopos, pkg, "extra", anyType)), false))
1472	pkg.Scope().Insert(obj)
1473
1474	// func panicrangestate()
1475	obj = types2.NewFunc(nopos, pkg, "panicrangestate", types2.NewSignatureType(nil, nil, nil, types2.NewTuple(types2.NewParam(nopos, pkg, "state", intType)), nil, false))
1476	pkg.Scope().Insert(obj)
1477
1478	return pkg
1479}()
1480
1481// runtimeSym returns a reference to a symbol in the fake runtime package.
1482func runtimeSym(info *types2.Info, name string) *syntax.Name {
1483	obj := runtimePkg.Scope().Lookup(name)
1484	n := syntax.NewName(nopos, "runtime."+name)
1485	tv := syntax.TypeAndValue{Type: obj.Type()}
1486	tv.SetIsValue()
1487	tv.SetIsRuntimeHelper()
1488	n.SetTypeInfo(tv)
1489	info.Uses[n] = obj
1490	return n
1491}
1492
1493// setPos walks the top structure of x that has no position assigned
1494// and assigns it all to have position pos.
1495// When setPos encounters a syntax node with a position assigned,
1496// setPos does not look inside that node.
1497// setPos only needs to handle syntax we create in this package;
1498// all other syntax should have positions assigned already.
1499func setPos(x syntax.Node, pos syntax.Pos) {
1500	if x == nil {
1501		return
1502	}
1503	syntax.Inspect(x, func(n syntax.Node) bool {
1504		if n == nil || n.Pos() != nopos {
1505			return false
1506		}
1507		n.SetPos(pos)
1508		switch n := n.(type) {
1509		case *syntax.BlockStmt:
1510			if n.Rbrace == nopos {
1511				n.Rbrace = pos
1512			}
1513		}
1514		return true
1515	})
1516}
1517