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.
All range types except
RangeInclusivecan be used in const generics:This compiles (on nightly), while the following does not:
This is because
RangeInclusivedoes not implementStructuralPartialEqandStructuralEq(#63438).RangeInclusivehas fieldsstartandendsimilar to the other range types, but also has an extra field:exhausted: bool(#68835). This was recently changed from a fieldis_empty: Option<bool>. This extra field tracks state for iteration and was added to address performance issues (#45222).The old implementation with
is_emptyhad semantic equality, however the new implementation withexhaustedhas structural equality:from range.rs
I believe this means we can either manually add implementations for
StructuralPartialEqandStructuralEq, or just derivePartialEqandEq, which will allowRangeInclusiveto also be used in const generics and remove the inconsistency with other range types.