Implement range syntax

Closes #19794

r? @aturon for the first patch
r? @nikomatsakis for the rest
This test doesn't detect the iteration being shorter than expected (or not occur at all), could be something like

```rust
let mut r = Range { ... };
let mut i = 0;
for ri in r {
    assert!(...);
    assert!(...);
    i += 1;
}
assert_eq!(i, 8);
```