about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-09-08 00:07:36 +0200
committerGitHub <noreply@github.com>2019-09-08 00:07:36 +0200
commitcd3cb281da9a4387f5896db75129d7dd73cca8f4 (patch)
treed19b29534ae871eaa6fdf621d2658dd041672075
parentcab2d84f061c624a016250458f29f0297b74d0fe (diff)
parent7b3f72906ffea5a8aec9e3d109d8e012f771a672 (diff)
downloadrust-cd3cb281da9a4387f5896db75129d7dd73cca8f4.tar.gz
rust-cd3cb281da9a4387f5896db75129d7dd73cca8f4.zip
Rollup merge of #64255 - varkor:bool-to-option, r=Centril
Add methods for converting `bool` to `Option<T>`

This provides a reference implementation for https://github.com/rust-lang/rfcs/pull/2757.
-rw-r--r--src/libcore/bool.rs45
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/tests/bool.rs7
-rw-r--r--src/libcore/tests/lib.rs2
-rw-r--r--src/librustc/middle/lang_items.rs1
-rw-r--r--src/librustc_typeck/check/method/probe.rs4
-rw-r--r--src/librustc_typeck/coherence/inherent_impls.rs8
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs1
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs1
10 files changed, 71 insertions, 1 deletions
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<T>(self, t: T) -> Option<T> {
+        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, F: FnOnce() -> T>(self, f: F) -> Option<T> {
+        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<DefId> {
         "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(),