about summary refs log tree commit diff
diff options
context:
space:
mode:
author许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com>2024-11-23 20:50:15 +0800
committerGitHub <noreply@github.com>2024-11-23 20:50:15 +0800
commit75b8f433e38dfed6aa16a42137bf048d8e668d27 (patch)
treec99066c6f99b6df10b438a81575603a3a75ba6cd
parent92f5144c9c30804384be66b3fc54e61d358d0114 (diff)
parent514ef180fd631b01c0f119991baaf217735ca849 (diff)
downloadrust-75b8f433e38dfed6aa16a42137bf048d8e668d27.tar.gz
rust-75b8f433e38dfed6aa16a42137bf048d8e668d27.zip
Rollup merge of #133237 - fee1-dead-contrib:constadd, r=compiler-errors
Minimally constify `Add`

* This PR removes the requirement for `impl const` to have a const stability attribute. cc ``@RalfJung`` I believe you mentioned that it would make much more sense to require `const_trait`s to have const stability instead. I agree with that sentiment but I don't think that is _required_ for a small scale experimentation like this PR. https://github.com/rust-lang/project-const-traits/issues/16 should definitely be prioritized in the future, but removing the impl check should be good for now as all callers need `const_trait_impl` enabled for any const impl to work.
* This PR is intentionally minimal as constifying other traits can become more complicated (`PartialEq`, for example, would run into requiring implementing it for `str` as that is used in matches, which runs into the implementation for slice equality which uses specialization)

Per the reasons above, anyone who is interested in making traits `const` in the standard library are **strongly encouraged** to reach out to us on the [Zulip channel](https://rust-lang.zulipchat.com/#narrow/channel/419616-t-compiler.2Fproject-const-traits) before proceeding with the work.

cc ``@rust-lang/project-const-traits``

I believe there is prior approval from libs that we can experiment, so

r? project-const-traits
-rw-r--r--compiler/rustc_passes/src/stability.rs11
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/ops/arith.rs13
-rw-r--r--tests/ui/stability-attribute/missing-const-stability.rs2
-rw-r--r--tests/ui/stability-attribute/missing-const-stability.stderr11
-rw-r--r--tests/ui/traits/const-traits/call-const-trait-method-pass.stderr19
-rw-r--r--tests/ui/traits/const-traits/const-and-non-const-impl.stderr20
-rw-r--r--tests/ui/traits/const-traits/generic-bound.rs3
-rw-r--r--tests/ui/traits/const-traits/generic-bound.stderr20
9 files changed, 21 insertions, 79 deletions
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 4a793f1875e..2809ad453ff 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -590,16 +590,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
     }
 
     fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) {
-        // if the const impl is derived using the `derive_const` attribute,
-        // then it would be "stable" at least for the impl.
-        // We gate usages of it using `feature(const_trait_impl)` anyways
-        // so there is no unstable leakage
-        if self.tcx.is_automatically_derived(def_id.to_def_id()) {
-            return;
-        }
-
-        let is_const = self.tcx.is_const_fn(def_id.to_def_id())
-            || self.tcx.is_const_trait_impl(def_id.to_def_id());
+        let is_const = self.tcx.is_const_fn(def_id.to_def_id());
 
         // Reachable const fn must have a stability attribute.
         if is_const
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index d30bf96cfd4..0706276dff9 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -174,6 +174,7 @@
 #![feature(const_is_char_boundary)]
 #![feature(const_precise_live_drops)]
 #![feature(const_str_split_at)]
+#![feature(const_trait_impl)]
 #![feature(decl_macro)]
 #![feature(deprecated_suggestion)]
 #![feature(doc_cfg)]
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
index 133ae04f026..565bccf5898 100644
--- a/library/core/src/ops/arith.rs
+++ b/library/core/src/ops/arith.rs
@@ -73,6 +73,7 @@
     append_const_msg
 )]
 #[doc(alias = "+")]
+#[cfg_attr(not(bootstrap), const_trait)]
 pub trait Add<Rhs = Self> {
     /// The resulting type after applying the `+` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -94,6 +95,7 @@ pub trait Add<Rhs = Self> {
 macro_rules! add_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(bootstrap)]
         impl Add for $t {
             type Output = $t;
 
@@ -103,6 +105,17 @@ macro_rules! add_impl {
             fn add(self, other: $t) -> $t { self + other }
         }
 
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(not(bootstrap))]
+        impl const Add for $t {
+            type Output = $t;
+
+            #[inline]
+            #[track_caller]
+            #[rustc_inherit_overflow_checks]
+            fn add(self, other: $t) -> $t { self + other }
+        }
+
         forward_ref_binop! { impl Add, add for $t, $t }
     )*)
 }
diff --git a/tests/ui/stability-attribute/missing-const-stability.rs b/tests/ui/stability-attribute/missing-const-stability.rs
index 10c31d79438..19820730736 100644
--- a/tests/ui/stability-attribute/missing-const-stability.rs
+++ b/tests/ui/stability-attribute/missing-const-stability.rs
@@ -27,7 +27,7 @@ pub trait Bar {
 }
 #[stable(feature = "stable", since = "1.0.0")]
 impl const Bar for Foo {
-    //~^ ERROR implementation has missing const stability attribute
+    // ok because all users must enable `const_trait_impl`
     fn fun() {}
 }
 
diff --git a/tests/ui/stability-attribute/missing-const-stability.stderr b/tests/ui/stability-attribute/missing-const-stability.stderr
index ad8a1fa9d36..baa4c34af06 100644
--- a/tests/ui/stability-attribute/missing-const-stability.stderr
+++ b/tests/ui/stability-attribute/missing-const-stability.stderr
@@ -4,15 +4,6 @@ error: function has missing const stability attribute
 LL | pub const fn foo() {}
    | ^^^^^^^^^^^^^^^^^^^^^
 
-error: implementation has missing const stability attribute
-  --> $DIR/missing-const-stability.rs:29:1
-   |
-LL | / impl const Bar for Foo {
-LL | |
-LL | |     fn fun() {}
-LL | | }
-   | |_^
-
 error: function has missing const stability attribute
   --> $DIR/missing-const-stability.rs:36:1
    |
@@ -25,5 +16,5 @@ error: associated function has missing const stability attribute
 LL |     pub const fn foo() {}
    |     ^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
index 9ae1ed18e35..1e48a0331cc 100644
--- a/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
+++ b/tests/ui/traits/const-traits/call-const-trait-method-pass.stderr
@@ -1,12 +1,3 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/call-const-trait-method-pass.rs:7:12
-   |
-LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
   --> $DIR/call-const-trait-method-pass.rs:15:12
    |
@@ -16,14 +7,6 @@ LL | impl const PartialEq for Int {
    = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
    = note: adding a non-const method body in the future would be a breaking change
 
-error[E0015]: cannot call non-const operator in constants
-  --> $DIR/call-const-trait-method-pass.rs:39:22
-   |
-LL | const ADD_INT: Int = Int(1i32) + Int(2i32);
-   |                      ^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
-
 error[E0015]: cannot call non-const fn `<Int as PartialEq>::eq` in constant functions
   --> $DIR/call-const-trait-method-pass.rs:20:15
    |
@@ -32,6 +15,6 @@ LL |         !self.eq(other)
    |
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-and-non-const-impl.stderr b/tests/ui/traits/const-traits/const-and-non-const-impl.stderr
index cf7af41cd4e..4eb15177347 100644
--- a/tests/ui/traits/const-traits/const-and-non-const-impl.stderr
+++ b/tests/ui/traits/const-traits/const-and-non-const-impl.stderr
@@ -1,21 +1,3 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/const-and-non-const-impl.rs:7:12
-   |
-LL | impl const std::ops::Add for i32 {
-   |            ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/const-and-non-const-impl.rs:23:12
-   |
-LL | impl const std::ops::Add for Int {
-   |            ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
 error[E0119]: conflicting implementations of trait `Add` for type `Int`
   --> $DIR/const-and-non-const-impl.rs:23:1
    |
@@ -38,7 +20,7 @@ LL | impl const std::ops::Add for i32 {
    = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
    = note: define and implement a trait or new type instead
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0117, E0119.
 For more information about an error, try `rustc --explain E0117`.
diff --git a/tests/ui/traits/const-traits/generic-bound.rs b/tests/ui/traits/const-traits/generic-bound.rs
index 620e3259917..5eb236acde2 100644
--- a/tests/ui/traits/const-traits/generic-bound.rs
+++ b/tests/ui/traits/const-traits/generic-bound.rs
@@ -1,4 +1,4 @@
-//@ known-bug: #110395
+//@ check-pass
 
 #![feature(const_trait_impl)]
 
@@ -26,5 +26,6 @@ const fn twice<T: std::ops::Add>(arg: S<T>) -> S<T> {
 }
 
 fn main() {
+    const _: S<i32> = twice(S(PhantomData));
     let _ = twice(S(PhantomData::<i32>));
 }
diff --git a/tests/ui/traits/const-traits/generic-bound.stderr b/tests/ui/traits/const-traits/generic-bound.stderr
deleted file mode 100644
index 0444c319577..00000000000
--- a/tests/ui/traits/const-traits/generic-bound.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error: const `impl` for trait `Add` which is not marked with `#[const_trait]`
-  --> $DIR/generic-bound.rs:16:15
-   |
-LL | impl<T> const std::ops::Add for S<T> {
-   |               ^^^^^^^^^^^^^
-   |
-   = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
-   = note: adding a non-const method body in the future would be a breaking change
-
-error[E0015]: cannot call non-const operator in constant functions
-  --> $DIR/generic-bound.rs:25:5
-   |
-LL |     arg + arg
-   |     ^^^^^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0015`.