about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-09-30 10:35:24 +0000
committerbors <bors@rust-lang.org>2021-09-30 10:35:24 +0000
commitc6007fdc7059c677a6c089e8d2915b264c0d1326 (patch)
treec2cf1599068de9c7cc903ccbc8029dc4ee69aa9c
parent69c1c6a173dcae20c245348f6c7d19074b6109b7 (diff)
parent29029c0bc2383441412f696e430aaa3536b04e37 (diff)
downloadrust-c6007fdc7059c677a6c089e8d2915b264c0d1326.tar.gz
rust-c6007fdc7059c677a6c089e8d2915b264c0d1326.zip
Auto merge of #86853 - usbalbin:const_try, r=oli-obk
Constify ?-operator for Result and Option

Try to make `?`-operator usable in `const fn` with `Result` and `Option`, see #74935 . Note that the try-operator itself was constified in #87237.

TODO
* [x] Add tests for const T -> T conversions
* [x] cleanup commits
* [x] Remove `#![allow(incomplete_features)]`
* [?] Await decision in #86808 - I'm not sure
* [x] Await support for parsing `~const` in bootstrapping compiler
* [x] Tracking issue(s)? - #88674
-rw-r--r--library/core/src/convert/mod.rs8
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/option.rs6
-rw-r--r--library/core/src/result.rs8
-rw-r--r--library/core/tests/convert.rs16
-rw-r--r--library/core/tests/lib.rs4
-rw-r--r--src/test/ui/consts/try-operator.rs23
7 files changed, 58 insertions, 8 deletions
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index 1e512af4805..72dbe845c97 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -532,9 +532,10 @@ where
 
 // From implies Into
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U> Into<U> for T
+#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
+impl<T, U> const Into<U> for T
 where
-    U: From<T>,
+    U: ~const From<T>,
 {
     fn into(self) -> U {
         U::from(self)
@@ -543,7 +544,8 @@ where
 
 // From (and thus Into) is reflexive
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> From<T> for T {
+#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
+impl<T> const From<T> for T {
     fn from(t: T) -> T {
         t
     }
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 265ba9f1bb9..9c4429d320f 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -82,6 +82,7 @@
 #![feature(const_float_bits_conv)]
 #![feature(const_float_classify)]
 #![feature(const_heap)]
+#![feature(const_convert)]
 #![feature(const_inherent_unchecked_arith)]
 #![feature(const_int_unchecked_arith)]
 #![feature(const_intrinsic_copy)]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 94d892dd787..a162c0340fb 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -2019,7 +2019,8 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
 }
 
 #[unstable(feature = "try_trait_v2", issue = "84277")]
-impl<T> ops::Try for Option<T> {
+#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
+impl<T> const ops::Try for Option<T> {
     type Output = T;
     type Residual = Option<convert::Infallible>;
 
@@ -2038,7 +2039,8 @@ impl<T> ops::Try for Option<T> {
 }
 
 #[unstable(feature = "try_trait_v2", issue = "84277")]
-impl<T> ops::FromResidual for Option<T> {
+#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
+impl<T> const ops::FromResidual for Option<T> {
     #[inline]
     fn from_residual(residual: Option<convert::Infallible>) -> Self {
         match residual {
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 4a300f857e9..bd4e623732e 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1889,7 +1889,8 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
 }
 
 #[unstable(feature = "try_trait_v2", issue = "84277")]
-impl<T, E> ops::Try for Result<T, E> {
+#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
+impl<T, E> const ops::Try for Result<T, E> {
     type Output = T;
     type Residual = Result<convert::Infallible, E>;
 
@@ -1908,7 +1909,10 @@ impl<T, E> ops::Try for Result<T, E> {
 }
 
 #[unstable(feature = "try_trait_v2", issue = "84277")]
-impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Result<T, F> {
+#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
+impl<T, E, F: ~const From<E>> const ops::FromResidual<Result<convert::Infallible, E>>
+    for Result<T, F>
+{
     #[inline]
     fn from_residual(residual: Result<convert::Infallible, E>) -> Self {
         match residual {
diff --git a/library/core/tests/convert.rs b/library/core/tests/convert.rs
new file mode 100644
index 00000000000..f1048f4cf09
--- /dev/null
+++ b/library/core/tests/convert.rs
@@ -0,0 +1,16 @@
+#[test]
+fn convert() {
+    const fn from(x: i32) -> i32 {
+        i32::from(x)
+    }
+
+    const FOO: i32 = from(42);
+    assert_eq!(FOO, 42);
+
+    const fn into(x: Vec<String>) -> Vec<String> {
+        x.into()
+    }
+
+    const BAR: Vec<String> = into(Vec::new());
+    assert_eq!(BAR, Vec::<String>::new());
+}
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index cd3aed4cd28..f25106abc88 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -9,12 +9,13 @@
 #![feature(cfg_target_has_atomic)]
 #![feature(const_assume)]
 #![feature(const_cell_into_inner)]
+#![feature(const_convert)]
 #![feature(const_maybe_uninit_assume_init)]
+#![feature(const_num_from_num)]
 #![feature(const_ptr_read)]
 #![feature(const_ptr_write)]
 #![feature(const_ptr_offset)]
 #![feature(const_trait_impl)]
-#![feature(const_num_from_num)]
 #![feature(core_intrinsics)]
 #![feature(core_private_bignum)]
 #![feature(core_private_diy_float)]
@@ -83,6 +84,7 @@ mod char;
 mod clone;
 mod cmp;
 mod const_ptr;
+mod convert;
 mod fmt;
 mod hash;
 mod intrinsics;
diff --git a/src/test/ui/consts/try-operator.rs b/src/test/ui/consts/try-operator.rs
new file mode 100644
index 00000000000..fe43b132cbd
--- /dev/null
+++ b/src/test/ui/consts/try-operator.rs
@@ -0,0 +1,23 @@
+// run-pass
+
+#![feature(try_trait_v2)]
+#![feature(const_trait_impl)]
+#![feature(const_try)]
+#![feature(const_convert)]
+
+fn main() {
+    const fn result() -> Result<bool, ()> {
+        Err(())?;
+        Ok(true)
+    }
+
+    const FOO: Result<bool, ()> = result();
+    assert_eq!(Err(()), FOO);
+
+    const fn option() -> Option<()> {
+        None?;
+        Some(())
+    }
+    const BAR: Option<()> = option();
+    assert_eq!(None, BAR);
+}