Reputation: 1540
There are multiple Range
types. Some Range
types implement Iterator
. I want to take all Range
types that implement Iterator
as a struct field.
This is my approach:
pub trait RangeBoundsExt<T: PartialOrd<T>>: Iterator<Item = T> {
// some methods
}
impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::Range<T> {}
impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeFrom<T> {}
impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeInclusive<T> {}
pub struct Foo<T> {
range: Box<dyn RangeBoundsExt<T>>
}
But I am getting this error:
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `T: std::iter::Step` is not satisfied
--> src/lib.rs:7:24
|
7 | impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::Range<T> {}
| ^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `T`
|
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::Range<T>`
help: consider further restricting this bound
|
7 | impl<T: PartialOrd<T> + std::iter::Step> RangeBoundsExt<T> for std::ops::Range<T> {}
| ^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `T: std::iter::Step` is not satisfied
--> src/lib.rs:9:24
|
9 | impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeFrom<T> {}
| ^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `T`
|
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::RangeFrom<T>`
help: consider further restricting this bound
|
9 | impl<T: PartialOrd<T> + std::iter::Step> RangeBoundsExt<T> for std::ops::RangeFrom<T> {}
| ^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `T: std::iter::Step` is not satisfied
--> src/lib.rs:11:24
|
11 | impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeInclusive<T> {}
| ^^^^^^^^^^^^^^^^^ the trait `std::iter::Step` is not implemented for `T`
|
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::ops::RangeInclusive<T>`
help: consider further restricting this bound
|
11 | impl<T: PartialOrd<T> + std::iter::Step> RangeBoundsExt<T> for std::ops::RangeInclusive<T> {}
| ^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.
Upvotes: 1
Views: 1029
Reputation: 35512
Range
does not guarantee an Iterator
implementation. It only provides one if the type implements Step
. Likewise, RangeTo
does not guarantee a lack of an Iterator
implementation. It simply just doesn't provide one by default. To fix your error, you simply have to require that there is an iterator definition for the range:
// note the additional 'where' requirement
impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::Range<T> where
std::ops::Range<T>: Iterator<Item = T>
{
}
impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeFrom<T> where
std::ops::RangeFrom<T>: Iterator<Item = T>
{
}
impl<T: PartialOrd<T>> RangeBoundsExt<T> for std::ops::RangeInclusive<T> where
std::ops::RangeInclusive<T>: Iterator<Item = T>
{
}
Upvotes: 1