-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
All range types except RangeInclusive can be used in const generics:
#![feature(const_generics)]
struct A<const R: Range<usize>>;
struct B<const R: RangeTo<usize>>;
struct C<const R: RangeFrom<usize>>;
struct D<const R: RangeToInclusive<usize>>;
struct E<const R: RangeFull<usize>>;This compiles (on nightly), while the following does not:
#![feature(const_generics)]
struct S<const R: RangeInclusive<usize>>;This is because RangeInclusive does not implement StructuralPartialEq and StructuralEq (#63438). RangeInclusive has fields start and end similar to the other range types, but also has an extra field: exhausted: bool (#68835). This was recently changed from a field is_empty: Option<bool>. This extra field tracks state for iteration and was added to address performance issues (#45222).
The old implementation with is_empty had semantic equality, however the new implementation with exhausted has structural equality:
impl<Idx: PartialEq> PartialEq for RangeInclusive<Idx> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.start == other.start && self.end == other.end && self.exhausted == other.exhausted
}
} from range.rs
I believe this means we can either manually add implementations for StructuralPartialEq and StructuralEq, or just derive PartialEq and Eq, which will allow RangeInclusive to also be used in const generics and remove the inconsistency with other range types.