Skip to content

Commit 9a9cbd6

Browse files
committed
Make Option fns const
With #49146 merged, many Option functions can be made const; some are still left out, like `Option.contains` (which requires PartialEq, and trait functions cannot be const), but it's a good start.
1 parent 0de96d3 commit 9a9cbd6

File tree

3 files changed

+345
-0
lines changed

3 files changed

+345
-0
lines changed

src/libcore/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
#![feature(maybe_uninit_slice)]
129129
#![feature(external_doc)]
130130
#![feature(associated_type_bounds)]
131+
#![cfg_attr(not(bootstrap), feature(const_if_match))]
131132

132133
#[prelude_import]
133134
#[allow(unused)]

src/libcore/option.rs

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,20 @@ impl<T> Option<T> {
183183
/// ```
184184
///
185185
/// [`Some`]: #variant.Some
186+
#[rustc_const_unstable(feature = "const_option_match")]
187+
#[cfg(not(bootstrap))]
188+
#[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"]
189+
#[inline]
190+
#[stable(feature = "rust1", since = "1.0.0")]
191+
pub const fn is_some(&self) -> bool {
192+
match *self {
193+
Some(_) => true,
194+
None => false,
195+
}
196+
}
197+
198+
/// No docs for bootstrap.
199+
#[cfg(bootstrap)]
186200
#[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"]
187201
#[inline]
188202
#[stable(feature = "rust1", since = "1.0.0")]
@@ -206,6 +220,18 @@ impl<T> Option<T> {
206220
/// ```
207221
///
208222
/// [`None`]: #variant.None
223+
#[rustc_const_unstable(feature = "const_option_match")]
224+
#[cfg(not(bootstrap))]
225+
#[must_use = "if you intended to assert that this doesn't have a value, consider \
226+
`.and_then(|| panic!(\"`Option` had a value when expected `None`\"))` instead"]
227+
#[inline]
228+
#[stable(feature = "rust1", since = "1.0.0")]
229+
pub const fn is_none(&self) -> bool {
230+
!self.is_some()
231+
}
232+
233+
/// No docs for bootstrap.
234+
#[cfg(bootstrap)]
209235
#[must_use = "if you intended to assert that this doesn't have a value, consider \
210236
`.and_then(|| panic!(\"`Option` had a value when expected `None`\"))` instead"]
211237
#[inline]
@@ -267,6 +293,19 @@ impl<T> Option<T> {
267293
/// let text_length: Option<usize> = text.as_ref().map(|s| s.len());
268294
/// println!("still can print text: {:?}", text);
269295
/// ```
296+
#[rustc_const_unstable(feature = "const_option_match")]
297+
#[cfg(not(bootstrap))]
298+
#[inline]
299+
#[stable(feature = "rust1", since = "1.0.0")]
300+
pub const fn as_ref(&self) -> Option<&T> {
301+
match *self {
302+
Some(ref x) => Some(x),
303+
None => None,
304+
}
305+
}
306+
307+
/// No docs for bootstrap.
308+
#[cfg(bootstrap)]
270309
#[inline]
271310
#[stable(feature = "rust1", since = "1.0.0")]
272311
pub fn as_ref(&self) -> Option<&T> {
@@ -340,6 +379,19 @@ impl<T> Option<T> {
340379
/// let x: Option<&str> = None;
341380
/// x.expect("the world is ending"); // panics with `the world is ending`
342381
/// ```
382+
#[rustc_const_unstable(feature = "const_option_match")]
383+
#[cfg(not(bootstrap))]
384+
#[inline]
385+
#[stable(feature = "rust1", since = "1.0.0")]
386+
pub const fn expect(self, msg: &str) -> T {
387+
match self {
388+
Some(val) => val,
389+
None => expect_failed(msg),
390+
}
391+
}
392+
393+
/// No docs for bootstrap.
394+
#[cfg(bootstrap)]
343395
#[inline]
344396
#[stable(feature = "rust1", since = "1.0.0")]
345397
pub fn expect(self, msg: &str) -> T {
@@ -396,6 +448,19 @@ impl<T> Option<T> {
396448
/// assert_eq!(Some("car").unwrap_or("bike"), "car");
397449
/// assert_eq!(None.unwrap_or("bike"), "bike");
398450
/// ```
451+
#[rustc_const_unstable(feature = "const_option_match")]
452+
#[cfg(not(bootstrap))]
453+
#[inline]
454+
#[stable(feature = "rust1", since = "1.0.0")]
455+
pub const fn unwrap_or(self, default: T) -> T {
456+
match self {
457+
Some(x) => x,
458+
None => default,
459+
}
460+
}
461+
462+
/// No docs for bootstrap.
463+
#[cfg(bootstrap)]
399464
#[inline]
400465
#[stable(feature = "rust1", since = "1.0.0")]
401466
pub fn unwrap_or(self, default: T) -> T {
@@ -414,6 +479,19 @@ impl<T> Option<T> {
414479
/// assert_eq!(Some(4).unwrap_or_else(|| 2 * k), 4);
415480
/// assert_eq!(None.unwrap_or_else(|| 2 * k), 20);
416481
/// ```
482+
#[rustc_const_unstable(feature = "const_option_match")]
483+
#[cfg(not(bootstrap))]
484+
#[inline]
485+
#[stable(feature = "rust1", since = "1.0.0")]
486+
pub const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
487+
match self {
488+
Some(x) => x,
489+
None => f(),
490+
}
491+
}
492+
493+
/// No docs for bootstrap.
494+
#[cfg(bootstrap)]
417495
#[inline]
418496
#[stable(feature = "rust1", since = "1.0.0")]
419497
pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
@@ -443,6 +521,19 @@ impl<T> Option<T> {
443521
///
444522
/// assert_eq!(maybe_some_len, Some(13));
445523
/// ```
524+
#[rustc_const_unstable(feature = "const_option_match")]
525+
#[cfg(not(bootstrap))]
526+
#[inline]
527+
#[stable(feature = "rust1", since = "1.0.0")]
528+
pub const fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
529+
match self {
530+
Some(x) => Some(f(x)),
531+
None => None,
532+
}
533+
}
534+
535+
/// No docs for bootstrap.
536+
#[cfg(bootstrap)]
446537
#[inline]
447538
#[stable(feature = "rust1", since = "1.0.0")]
448539
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
@@ -464,6 +555,19 @@ impl<T> Option<T> {
464555
/// let x: Option<&str> = None;
465556
/// assert_eq!(x.map_or(42, |v| v.len()), 42);
466557
/// ```
558+
#[rustc_const_unstable(feature = "const_option_match")]
559+
#[cfg(not(bootstrap))]
560+
#[inline]
561+
#[stable(feature = "rust1", since = "1.0.0")]
562+
pub const fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
563+
match self {
564+
Some(t) => f(t),
565+
None => default,
566+
}
567+
}
568+
569+
/// No docs for bootstrap.
570+
#[cfg(bootstrap)]
467571
#[inline]
468572
#[stable(feature = "rust1", since = "1.0.0")]
469573
pub fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
@@ -487,6 +591,19 @@ impl<T> Option<T> {
487591
/// let x: Option<&str> = None;
488592
/// assert_eq!(x.map_or_else(|| 2 * k, |v| v.len()), 42);
489593
/// ```
594+
#[rustc_const_unstable(feature = "const_option_match")]
595+
#[cfg(not(bootstrap))]
596+
#[inline]
597+
#[stable(feature = "rust1", since = "1.0.0")]
598+
pub const fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
599+
match self {
600+
Some(t) => f(t),
601+
None => default(),
602+
}
603+
}
604+
605+
/// No docs for bootstrap.
606+
#[cfg(bootstrap)]
490607
#[inline]
491608
#[stable(feature = "rust1", since = "1.0.0")]
492609
pub fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
@@ -519,6 +636,19 @@ impl<T> Option<T> {
519636
/// let x: Option<&str> = None;
520637
/// assert_eq!(x.ok_or(0), Err(0));
521638
/// ```
639+
#[rustc_const_unstable(feature = "const_option_match")]
640+
#[cfg(not(bootstrap))]
641+
#[inline]
642+
#[stable(feature = "rust1", since = "1.0.0")]
643+
pub const fn ok_or<E>(self, err: E) -> Result<T, E> {
644+
match self {
645+
Some(v) => Ok(v),
646+
None => Err(err),
647+
}
648+
}
649+
650+
/// No docs for bootstrap.
651+
#[cfg(bootstrap)]
522652
#[inline]
523653
#[stable(feature = "rust1", since = "1.0.0")]
524654
pub fn ok_or<E>(self, err: E) -> Result<T, E> {
@@ -546,6 +676,19 @@ impl<T> Option<T> {
546676
/// let x: Option<&str> = None;
547677
/// assert_eq!(x.ok_or_else(|| 0), Err(0));
548678
/// ```
679+
#[rustc_const_unstable(feature = "const_option_match")]
680+
#[cfg(not(bootstrap))]
681+
#[inline]
682+
#[stable(feature = "rust1", since = "1.0.0")]
683+
pub const fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
684+
match self {
685+
Some(v) => Ok(v),
686+
None => Err(err()),
687+
}
688+
}
689+
690+
/// No docs for bootstrap.
691+
#[cfg(bootstrap)]
549692
#[inline]
550693
#[stable(feature = "rust1", since = "1.0.0")]
551694
pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
@@ -624,6 +767,19 @@ impl<T> Option<T> {
624767
/// let y: Option<&str> = None;
625768
/// assert_eq!(x.and(y), None);
626769
/// ```
770+
#[rustc_const_unstable(feature = "const_option_match")]
771+
#[cfg(not(bootstrap))]
772+
#[inline]
773+
#[stable(feature = "rust1", since = "1.0.0")]
774+
pub const fn and<U>(self, optb: Option<U>) -> Option<U> {
775+
match self {
776+
Some(_) => optb,
777+
None => None,
778+
}
779+
}
780+
781+
/// No docs for bootstrap.
782+
#[cfg(bootstrap)]
627783
#[inline]
628784
#[stable(feature = "rust1", since = "1.0.0")]
629785
pub fn and<U>(self, optb: Option<U>) -> Option<U> {
@@ -651,6 +807,19 @@ impl<T> Option<T> {
651807
/// assert_eq!(Some(2).and_then(nope).and_then(sq), None);
652808
/// assert_eq!(None.and_then(sq).and_then(sq), None);
653809
/// ```
810+
#[rustc_const_unstable(feature = "const_option_match")]
811+
#[cfg(not(bootstrap))]
812+
#[inline]
813+
#[stable(feature = "rust1", since = "1.0.0")]
814+
pub const fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
815+
match self {
816+
Some(x) => f(x),
817+
None => None,
818+
}
819+
}
820+
821+
/// No docs for bootstrap.
822+
#[cfg(bootstrap)]
654823
#[inline]
655824
#[stable(feature = "rust1", since = "1.0.0")]
656825
pub fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
@@ -686,6 +855,21 @@ impl<T> Option<T> {
686855
/// [`None`]: #variant.None
687856
/// [`Some(t)`]: #variant.Some
688857
/// [`Iterator::filter()`]: ../../std/iter/trait.Iterator.html#method.filter
858+
#[rustc_const_unstable(feature = "const_option_match")]
859+
#[cfg(not(bootstrap))]
860+
#[inline]
861+
#[stable(feature = "option_filter", since = "1.27.0")]
862+
pub const fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Self {
863+
if let Some(x) = self {
864+
if predicate(&x) {
865+
return Some(x);
866+
}
867+
}
868+
None
869+
}
870+
871+
/// No docs for bootstrap.
872+
#[cfg(bootstrap)]
689873
#[inline]
690874
#[stable(feature = "option_filter", since = "1.27.0")]
691875
pub fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Self {
@@ -724,6 +908,19 @@ impl<T> Option<T> {
724908
/// let y = None;
725909
/// assert_eq!(x.or(y), None);
726910
/// ```
911+
#[rustc_const_unstable(feature = "const_option_match")]
912+
#[cfg(not(bootstrap))]
913+
#[inline]
914+
#[stable(feature = "rust1", since = "1.0.0")]
915+
pub const fn or(self, optb: Option<T>) -> Option<T> {
916+
match self {
917+
Some(_) => self,
918+
None => optb,
919+
}
920+
}
921+
922+
/// No docs for bootstrap.
923+
#[cfg(bootstrap)]
727924
#[inline]
728925
#[stable(feature = "rust1", since = "1.0.0")]
729926
pub fn or(self, optb: Option<T>) -> Option<T> {
@@ -746,6 +943,19 @@ impl<T> Option<T> {
746943
/// assert_eq!(None.or_else(vikings), Some("vikings"));
747944
/// assert_eq!(None.or_else(nobody), None);
748945
/// ```
946+
#[rustc_const_unstable(feature = "const_option_match")]
947+
#[cfg(not(bootstrap))]
948+
#[inline]
949+
#[stable(feature = "rust1", since = "1.0.0")]
950+
pub const fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> {
951+
match self {
952+
Some(_) => self,
953+
None => f(),
954+
}
955+
}
956+
957+
/// No docs for bootstrap.
958+
#[cfg(bootstrap)]
749959
#[inline]
750960
#[stable(feature = "rust1", since = "1.0.0")]
751961
pub fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> {
@@ -779,6 +989,20 @@ impl<T> Option<T> {
779989
/// let y: Option<u32> = None;
780990
/// assert_eq!(x.xor(y), None);
781991
/// ```
992+
#[rustc_const_unstable(feature = "const_option_match")]
993+
#[cfg(not(bootstrap))]
994+
#[inline]
995+
#[stable(feature = "option_xor", since = "1.37.0")]
996+
pub const fn xor(self, optb: Option<T>) -> Option<T> {
997+
match (self, optb) {
998+
(Some(a), None) => Some(a),
999+
(None, Some(b)) => Some(b),
1000+
_ => None,
1001+
}
1002+
}
1003+
1004+
/// No docs for bootstrap.
1005+
#[cfg(bootstrap)]
7821006
#[inline]
7831007
#[stable(feature = "option_xor", since = "1.37.0")]
7841008
pub fn xor(self, optb: Option<T>) -> Option<T> {

0 commit comments

Comments
 (0)