@@ -360,12 +360,13 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
360
360
val , _ := indirect (s .evalPipeline (dot , r .Pipe ))
361
361
// mark top of stack before any variables in the body are pushed.
362
362
mark := s .mark ()
363
+ var rangefunc = false
363
364
oneIteration := func (index , elem reflect.Value ) {
364
365
if len (r .Pipe .Decl ) > 0 {
365
- if r .Pipe .IsAssign {
366
+ if r .Pipe .IsAssign || rangefunc {
366
367
// With two variables, index comes first.
367
368
// With one, we use the element.
368
- if len (r .Pipe .Decl ) > 1 {
369
+ if len (r .Pipe .Decl ) > 1 || rangefunc {
369
370
s .setVar (r .Pipe .Decl [0 ].Ident [0 ], index )
370
371
} else {
371
372
s .setVar (r .Pipe .Decl [0 ].Ident [0 ], elem )
@@ -395,24 +396,6 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
395
396
s .walk (elem , r .List )
396
397
}
397
398
398
- rangeone := func (elem reflect.Value ) {
399
- if len (r .Pipe .Decl ) > 0 {
400
- s .setVar (r .Pipe .Decl [0 ].Ident [0 ], elem )
401
- }
402
- if len (r .Pipe .Decl ) > 1 {
403
- s .errorf ("can't use %v iterate over two variables" , val )
404
- return
405
- }
406
- defer s .pop (mark )
407
- defer func () {
408
- // Consume panic(walkContinue)
409
- if r := recover (); r != nil && r != walkContinue {
410
- panic (r )
411
- }
412
- }()
413
- s .walk (elem , r .List )
414
- }
415
-
416
399
switch val .Kind () {
417
400
case reflect .Array , reflect .Slice :
418
401
if val .Len () == 0 {
@@ -455,8 +438,13 @@ func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
455
438
break // An invalid value is likely a nil map, etc. and acts like an empty map.
456
439
case reflect .Func :
457
440
if val .Type ().CanSeq () {
441
+ if len (r .Pipe .Decl ) > 1 {
442
+ s .errorf ("range can't iterate over %v" , val )
443
+ return
444
+ }
445
+ rangefunc = true
458
446
for v := range val .Seq () {
459
- rangeone ( v )
447
+ oneIteration ( v , reflect. Value {} )
460
448
}
461
449
return
462
450
}
0 commit comments