From f0386a10e0112acef6ea0447e6e5a3ac1c7cb118 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Sat, 7 Sep 2019 13:16:18 +0100
Subject: [PATCH 1/4] Add "bool" lang item

---
 src/libcore/bool/mod.rs                          | 7 +++++++
 src/libcore/lib.rs                               | 1 +
 src/librustc/middle/lang_items.rs                | 1 +
 src/librustc_typeck/check/method/probe.rs        | 4 ++++
 src/librustc_typeck/coherence/inherent_impls.rs  | 8 ++++++++
 src/librustdoc/clean/mod.rs                      | 2 +-
 src/librustdoc/passes/collect_intra_doc_links.rs | 1 +
 src/librustdoc/passes/collect_trait_impls.rs     | 1 +
 8 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 src/libcore/bool/mod.rs

diff --git a/src/libcore/bool/mod.rs b/src/libcore/bool/mod.rs
new file mode 100644
index 0000000000000..ddca07b27a53f
--- /dev/null
+++ b/src/libcore/bool/mod.rs
@@ -0,0 +1,7 @@
+//! impl bool {}
+
+#![stable(feature = "core_bool", since = "1.39.0")]
+
+#[cfg(not(boostrap_stdarch_ignore_this))]
+#[lang = "bool"]
+impl bool {}
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index c168d5c8a2eac..03b6aa68d3c27 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -198,6 +198,7 @@ pub mod borrow;
 pub mod any;
 pub mod array;
 pub mod ascii;
+pub mod bool;
 pub mod sync;
 pub mod cell;
 pub mod char;
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 6b04600eb75f8..0aa708033c1a7 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -246,6 +246,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 1c01c8408be6c..c8838311e8dbf 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 fb79a85ea25bf..e7c2126cfd727 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 4971155113263..38eff43bad2be 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 2951b2ccb2af9..d6073cdc1e11d 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 86e4e9fd95637..28c64d0b9638e 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(),

From b73e32c795ec438a4b2e1901abc4e2a281e1a18a Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Sat, 7 Sep 2019 15:49:27 +0100
Subject: [PATCH 2/4] Add `bool::then` and `bool::then_with`

---
 src/libcore/bool/mod.rs   | 42 ++++++++++++++++++++++++++++++++++++++-
 src/libcore/tests/bool.rs |  7 +++++++
 src/libcore/tests/lib.rs  |  2 ++
 3 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 src/libcore/tests/bool.rs

diff --git a/src/libcore/bool/mod.rs b/src/libcore/bool/mod.rs
index ddca07b27a53f..0fbd3b8c2bbce 100644
--- a/src/libcore/bool/mod.rs
+++ b/src/libcore/bool/mod.rs
@@ -4,4 +4,44 @@
 
 #[cfg(not(boostrap_stdarch_ignore_this))]
 #[lang = "bool"]
-impl 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 = "0")]
+    #[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 = "0")]
+    #[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/tests/bool.rs b/src/libcore/tests/bool.rs
new file mode 100644
index 0000000000000..0f1e6e89451e9
--- /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 a3b108b2e9cea..b2c29aa269265 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;

From 0f0e1c1691422132a40e5f534ff579004a79ef9c Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Sat, 7 Sep 2019 17:04:19 +0100
Subject: [PATCH 3/4] Move `libcore/bool/mod.rs` to `libcore/bool.rs`

---
 src/libcore/{bool/mod.rs => bool.rs} | 2 --
 src/libcore/lib.rs                   | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)
 rename src/libcore/{bool/mod.rs => bool.rs} (95%)

diff --git a/src/libcore/bool/mod.rs b/src/libcore/bool.rs
similarity index 95%
rename from src/libcore/bool/mod.rs
rename to src/libcore/bool.rs
index 0fbd3b8c2bbce..54faa7047d5b8 100644
--- a/src/libcore/bool/mod.rs
+++ b/src/libcore/bool.rs
@@ -1,7 +1,5 @@
 //! impl bool {}
 
-#![stable(feature = "core_bool", since = "1.39.0")]
-
 #[cfg(not(boostrap_stdarch_ignore_this))]
 #[lang = "bool"]
 impl bool {
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 03b6aa68d3c27..690cff483b07c 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -198,7 +198,6 @@ pub mod borrow;
 pub mod any;
 pub mod array;
 pub mod ascii;
-pub mod bool;
 pub mod sync;
 pub mod cell;
 pub mod char;
@@ -228,6 +227,7 @@ pub mod task;
 pub mod alloc;
 
 // note: does not need to be public
+mod bool;
 mod tuple;
 mod unit;
 

From 7b3f72906ffea5a8aec9e3d109d8e012f771a672 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Sat, 7 Sep 2019 17:06:39 +0100
Subject: [PATCH 4/4] Add tracking issue

---
 src/libcore/bool.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs
index 54faa7047d5b8..32ec26975e375 100644
--- a/src/libcore/bool.rs
+++ b/src/libcore/bool.rs
@@ -13,7 +13,7 @@ impl bool {
     /// assert_eq!(false.then(0), None);
     /// assert_eq!(true.then(0), Some(0));
     /// ```
-    #[unstable(feature = "bool_to_option", issue = "0")]
+    #[unstable(feature = "bool_to_option", issue = "64260")]
     #[inline]
     pub fn then<T>(self, t: T) -> Option<T> {
         if self {
@@ -33,7 +33,7 @@ impl bool {
     /// assert_eq!(false.then_with(|| 0), None);
     /// assert_eq!(true.then_with(|| 0), Some(0));
     /// ```
-    #[unstable(feature = "bool_to_option", issue = "0")]
+    #[unstable(feature = "bool_to_option", issue = "64260")]
     #[inline]
     pub fn then_with<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
         if self {