diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs new file mode 100644 index 00000000000..32ec26975e3 --- /dev/null +++ b/src/libcore/bool.rs @@ -0,0 +1,45 @@ +//! impl bool {} + +#[cfg(not(boostrap_stdarch_ignore_this))] +#[lang = "bool"] +impl bool { + /// Returns `Some(t)` if the `bool` is `true`, or `None` otherwise. + /// + /// # Examples + /// + /// ``` + /// #![feature(bool_to_option)] + /// + /// assert_eq!(false.then(0), None); + /// assert_eq!(true.then(0), Some(0)); + /// ``` + #[unstable(feature = "bool_to_option", issue = "64260")] + #[inline] + pub fn then(self, t: T) -> Option { + if self { + Some(t) + } else { + None + } + } + + /// Returns `Some(f())` if the `bool` is `true`, or `None` otherwise. + /// + /// # Examples + /// + /// ``` + /// #![feature(bool_to_option)] + /// + /// assert_eq!(false.then_with(|| 0), None); + /// assert_eq!(true.then_with(|| 0), Some(0)); + /// ``` + #[unstable(feature = "bool_to_option", issue = "64260")] + #[inline] + pub fn then_with T>(self, f: F) -> Option { + if self { + Some(f()) + } else { + None + } + } +} diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index c168d5c8a2e..690cff483b0 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -227,6 +227,7 @@ pub mod task; pub mod alloc; // note: does not need to be public +mod bool; mod tuple; mod unit; diff --git a/src/libcore/tests/bool.rs b/src/libcore/tests/bool.rs new file mode 100644 index 00000000000..0f1e6e89451 --- /dev/null +++ b/src/libcore/tests/bool.rs @@ -0,0 +1,7 @@ +#[test] +fn test_bool_to_option() { + assert_eq!(false.then(0), None); + assert_eq!(true.then(0), Some(0)); + assert_eq!(false.then_with(|| 0), None); + assert_eq!(true.then_with(|| 0), Some(0)); +} diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index a3b108b2e9c..b2c29aa2692 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -1,3 +1,4 @@ +#![feature(bool_to_option)] #![feature(bound_cloned)] #![feature(box_syntax)] #![feature(cell_update)] @@ -40,6 +41,7 @@ mod any; mod array; mod ascii; mod atomic; +mod bool; mod cell; mod char; mod clone; diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 6dfd7a7f943..c5d9a722ae1 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -244,6 +244,7 @@ pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> LanguageItems { language_item_table! { // Variant name, Name, Method name, Target; + BoolImplItem, "bool", bool_impl, Target::Impl; CharImplItem, "char", char_impl, Target::Impl; StrImplItem, "str", str_impl, Target::Impl; SliceImplItem, "slice", slice_impl, Target::Impl; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 1c01c8408be..c8838311e8d 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -578,6 +578,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ty::Param(p) => { self.assemble_inherent_candidates_from_param(p); } + ty::Bool => { + let lang_def_id = lang_items.bool_impl(); + self.assemble_inherent_impl_for_primitive(lang_def_id); + } ty::Char => { let lang_def_id = lang_items.char_impl(); self.assemble_inherent_impl_for_primitive(lang_def_id); diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index fb79a85ea25..e7c2126cfd7 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -67,6 +67,14 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { ty::Dynamic(ref data, ..) if data.principal_def_id().is_some() => { self.check_def_id(item, data.principal_def_id().unwrap()); } + ty::Bool => { + self.check_primitive_impl(def_id, + lang_items.bool_impl(), + None, + "bool", + "bool", + item.span); + } ty::Char => { self.check_primitive_impl(def_id, lang_items.char_impl(), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 49711551132..38eff43bad2 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -3977,7 +3977,7 @@ fn build_deref_target_impls(cx: &DocContext<'_>, F32 => tcx.lang_items().f32_impl(), F64 => tcx.lang_items().f64_impl(), Char => tcx.lang_items().char_impl(), - Bool => None, + Bool => tcx.lang_items().bool_impl(), Str => tcx.lang_items().str_impl(), Slice => tcx.lang_items().slice_impl(), Array => tcx.lang_items().slice_impl(), diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 2951b2ccb2a..d6073cdc1e1 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -679,6 +679,7 @@ fn primitive_impl(cx: &DocContext<'_>, path_str: &str) -> Option { "f32" => tcx.lang_items().f32_impl(), "f64" => tcx.lang_items().f64_impl(), "str" => tcx.lang_items().str_impl(), + "bool" => tcx.lang_items().bool_impl(), "char" => tcx.lang_items().char_impl(), _ => None, } diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 86e4e9fd956..28c64d0b963 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -53,6 +53,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { lang_items.f64_impl(), lang_items.f32_runtime_impl(), lang_items.f64_runtime_impl(), + lang_items.bool_impl(), lang_items.char_impl(), lang_items.str_impl(), lang_items.slice_impl(),