-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Description
Code
fn custom_range() {
struct Foo(u32);
let x = Foo(0);
let y = Foo(10);
for value in x..y {}
}Current output
error[E0277]: the trait bound `Foo: Step` is not satisfied
--> src/lib.rs:7:18
|
7 | for value in x..y {}
| ^^^^ unsatisfied trait bound
|
help: the trait `Step` is not implemented for `Foo`
--> src/lib.rs:2:5
|
2 | struct Foo(u32);
| ^^^^^^^^^^
= note: required for `std::ops::Range<Foo>` to implement `Iterator`
= note: required for `std::ops::Range<Foo>` to implement `IntoIterator`Rationale and extra context
Users may encounter error messages saying some type does not implement the Step trait. These messages are not actionable, because the Step trait is unstable and in most cases there are limited options available to the user. This is hard to explain to beginners; if their mentor's explanation will be "yeah, that's kind of unhelpful; instead the error message should have said _____" then perhaps we could do better with the compiler diagnostics.
Instead of describing this as a typical trait failure, perhaps we should describe this as though it's an implementation detail of the standard library. This would avoid giving beginners the impression that they can somehow make it work if they knew the right syntax, which can be a frustrating experience.
Maybe the message should say something like:
`Range` only implements `Iterator` for select types in the standard library
(integers, `char`, and a few others).
To see the full list of types, see the documentation for the unstable `Step` trait.
I searched for other issues on this topic, and found it mentioned in #133511, which was resolved without providing any actionable help. The tracking issue for the Step trait is #42168. A few places where users have discussed it: 1, 2, 3, 4
Here are some additional examples where we might encounter errors mentioning the Step trait:
fn non_integer_range(x: f32, y: f32) {
for value in x..y {}
}error[E0277]: the trait bound `f32: Step` is not satisfied
--> src/lib.rs:15:18
|
15 | for value in x..y {}
| ^^^^ the trait `Step` is not implemented for `f32`
|
= help: the following other types implement trait `Step`:
i128
i16
i32
i64
i8
isize
u128
u16
and 4 others
= note: required for `std::ops::Range<f32>` to implement `Iterator`
= note: required for `std::ops::Range<f32>` to implement `IntoIterator`
fn in_trait_bounds<T>(x: T, y: T) {
for value in x..y {}
}error[E0277]: the trait bound `T: Step` is not satisfied
--> src/lib.rs:11:18
|
11 | for value in x..y {}
| ^^^^ the trait `Step` is not implemented for `T`
|
= note: required for `std::ops::Range<T>` to implement `Iterator`
= note: required for `std::ops::Range<T>` to implement `IntoIterator`
Rust Version
rustc 1.92.0 (ded5c06cf 2025-12-08)
binary: rustc
commit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234
commit-date: 2025-12-08
host: x86_64-unknown-linux-gnu
release: 1.92.0
LLVM version: 21.1.3