_linters/src/honnef.co/go/tools/ssa/builder.go
func (b *builder) rangeIter(fn *Function, x Value, tk, tv types.Type, pos token.Pos) (k, v Value, loop, done *BasicBlock) {
	//
	//	it = range x
	// loop:                                   (target of continue)
	//	okv = next it                      (ok, key, value)
	//  	ok = extract okv #0
	// 	if ok goto body else done
	// body:
	// 	k = extract okv #1
	// 	v = extract okv #2
	//      ...body...
	// 	jump loop
	// done:                                   (target of break)
	//

	if tk == nil {
		tk = tInvalid
	}
	if tv == nil {
		tv = tInvalid
	}

	rng := &Range{X: x}
	rng.setPos(pos)
	rng.setType(tRangeIter)
	it := fn.emit(rng)

	loop = fn.newBasicBlock("rangeiter.loop")
	emitJump(fn, loop)
	fn.currentBlock = loop

	_, isString := x.Type().Underlying().(*types.Basic)

	okv := &Next{
		Iter:     it,
		IsString: isString,
	}
	okv.setType(types.NewTuple(
		varOk,
		newVar("k", tk),
		newVar("v", tv),
	))
	fn.emit(okv)

	body := fn.newBasicBlock("rangeiter.body")
	done = fn.newBasicBlock("rangeiter.done")
	emitIf(fn, emitExtract(fn, okv, 0), body, done)
	fn.currentBlock = body

	if tk != tInvalid {
		k = emitExtract(fn, okv, 1)
	}
	if tv != tInvalid {
		v = emitExtract(fn, okv, 2)
	}
	return
}
func (b *builder) rangeIter(fn *Function, x Value, tk, tv types.Type, pos token.Pos) (k, v Value, loop, done *BasicBlock) {
	//
	//	it = range x
	// loop:                                   (target of continue)
	//	okv = next it                      (ok, key, value)
	//  	ok = extract okv #0
	// 	if ok goto body else done
	// body:
	// 	k = extract okv #1
	// 	v = extract okv #2
	//      ...body...
	// 	jump loop
	// done:                                   (target of break)
	//

	if tk == nil {
		tk = tInvalid
	}
	if tv == nil {
		tv = tInvalid
	}

	rng := &Range{X: x}
	rng.setPos(pos)
	rng.setType(tRangeIter)
	it := fn.emit(rng)

	loop = fn.newBasicBlock("rangeiter.loop")
	emitJump(fn, loop)
	fn.currentBlock = loop

	_, isString := x.Type().Underlying().(*types.Basic)

	okv := &Next{
		Iter:     it,
		IsString: isString,
	}
	okv.setType(types.NewTuple(
		varOk,
		newVar("k", tk),
		newVar("v", tv),
	))
	fn.emit(okv)

	body := fn.newBasicBlock("rangeiter.body")
	done = fn.newBasicBlock("rangeiter.done")
	emitIf(fn, emitExtract(fn, okv, 0), body, done)
	fn.currentBlock = body

	if tk != tInvalid {
		k = emitExtract(fn, okv, 1)
	}
	if tv != tInvalid {
		v = emitExtract(fn, okv, 2)
	}
	return
}
func ( b * builder ) rangeIter ( fn * Function , x Value , tk , tv types . Type , pos token . Pos ) ( k , v Value , loop , done * BasicBlock ) { // //	it = range x // loop:                                   (target of continue) //	okv = next it                      (ok, key, value) //  	ok = extract okv #0 // 	if ok goto body else done // body: // 	k = extract okv #1 // 	v = extract okv #2 //      ...body... // 	jump loop // done:                                   (target of break) // if tk == nil { tk = tInvalid } if tv == nil { tv = tInvalid } rng := & Range { X : x } rng . setPos ( pos ) rng . setType ( tRangeIter ) it := fn . emit ( rng ) loop = fn . newBasicBlock ( " " ) emitJump ( fn , loop ) fn . currentBlock = loop _ , isString := x . Type ( ) . Underlying ( ) . ( * types . Basic ) okv := & Next { Iter : it , IsString : isString , } okv . setType ( types . NewTuple ( varOk , newVar ( " " , tk ) , newVar ( " " , tv ) , ) ) fn . emit ( okv ) body := fn . newBasicBlock ( " " ) done = fn . newBasicBlock ( " " ) emitIf ( fn , emitExtract ( fn , okv , 0 ) , body , done ) fn . currentBlock = body if tk != tInvalid { k = emitExtract ( fn , okv , 1 ) } if tv != tInvalid { v = emitExtract ( fn , okv , 2 ) } return }
// rangeIter emits to fn the header for a loop using
// Range/Next/Extract to iterate over map or string value x.
// tk and tv are the types of the key/value results k and v, or nil
// if the respective component is not wanted.
//
rangeIter emits to fn the header for a loop using Range / Next / Extract to iterate over map or string value x . tk and tv are the types of the key / value results k and v or nil if the respective component is not wanted .