To elaborate on some previous answers:

This is not correct. A Range is, in fact, already an Iterator. The trouble here is that `rev()`

(and virtually all other iterator methods) returns an adapter type, and so it is almost never possible to have two iterator chains with the same statically known type.

```
let r = if start < end {
start..end // this is a Range<usize>
} else {
(start..end).rev() // this is a Rev<Range<usize>>
}
```

This is why @azriel91’s solution of collecting into a Vector, or @vitalyd’s solution of type erasure are necessary.

There is also a third solution. (actually, it’s just a small generalization of @azriel91’s) You can take the part of the code *after* the construction of the range, and move it into a generic function. This will work as long as you can pull out all of the code up to the point where you consume the iterator.

For instance, you can transform this: (which doesn’t compile)

```
let a = 2;
let b = 7;
let skip_evens = true;
let nums = if skip_evens {
(a..b).filter(|x| x % 2 == 1)
} else {
(a..b)
};
for n in nums {
println!("{}", n);
} // at this point nums has been consumed
```

into this:

```
let a = 2;
let b = 7;
let skip_evens = true;
if skip_evens {
rest_of_fn((a..b).filter(|x| x % 2 == 1))
} else {
rest_of_fn((a..b))
}
fn rest_of_fn<I: Iterator<Item=usize>>(nums: I) {
for n in nums {
println!("{}", n);
}
}
```