Skip to content

Commit ad3db57

Browse files
committed
Use Option's discriminant as its size hint
1 parent cac6664 commit ad3db57

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

core/src/option.rs

+17-7
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,13 @@ impl<T> Option<T> {
770770
}
771771
}
772772

773+
#[inline]
774+
const fn len(&self) -> usize {
775+
// Using the intrinsic avoids emitting a branch to get the 0 or 1.
776+
let discriminant: isize = crate::intrinsics::discriminant_value(self);
777+
discriminant as usize
778+
}
779+
773780
/// Returns a slice of the contained value, if any. If this is `None`, an
774781
/// empty slice is returned. This can be useful to have a single type of
775782
/// iterator over an `Option` or slice.
@@ -812,7 +819,7 @@ impl<T> Option<T> {
812819
unsafe {
813820
slice::from_raw_parts(
814821
(self as *const Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(),
815-
self.is_some() as usize,
822+
self.len(),
816823
)
817824
}
818825
}
@@ -869,7 +876,7 @@ impl<T> Option<T> {
869876
unsafe {
870877
slice::from_raw_parts_mut(
871878
(self as *mut Self).byte_add(core::mem::offset_of!(Self, Some.0)).cast(),
872-
self.is_some() as usize,
879+
self.len(),
873880
)
874881
}
875882
}
@@ -2242,10 +2249,8 @@ impl<A> Iterator for Item<A> {
22422249

22432250
#[inline]
22442251
fn size_hint(&self) -> (usize, Option<usize>) {
2245-
match self.opt {
2246-
Some(_) => (1, Some(1)),
2247-
None => (0, Some(0)),
2248-
}
2252+
let len = self.len();
2253+
(len, Some(len))
22492254
}
22502255
}
22512256

@@ -2256,7 +2261,12 @@ impl<A> DoubleEndedIterator for Item<A> {
22562261
}
22572262
}
22582263

2259-
impl<A> ExactSizeIterator for Item<A> {}
2264+
impl<A> ExactSizeIterator for Item<A> {
2265+
#[inline]
2266+
fn len(&self) -> usize {
2267+
self.opt.len()
2268+
}
2269+
}
22602270
impl<A> FusedIterator for Item<A> {}
22612271
unsafe impl<A> TrustedLen for Item<A> {}
22622272

0 commit comments

Comments
 (0)