diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2024-11-23 20:50:15 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-23 20:50:15 +0800 |
| commit | 75b8f433e38dfed6aa16a42137bf048d8e668d27 (patch) | |
| tree | c99066c6f99b6df10b438a81575603a3a75ba6cd | |
| parent | 92f5144c9c30804384be66b3fc54e61d358d0114 (diff) | |
| parent | 514ef180fd631b01c0f119991baaf217735ca849 (diff) | |
| download | rust-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.rs | 11 | ||||
| -rw-r--r-- | library/core/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/core/src/ops/arith.rs | 13 | ||||
| -rw-r--r-- | tests/ui/stability-attribute/missing-const-stability.rs | 2 | ||||
| -rw-r--r-- | tests/ui/stability-attribute/missing-const-stability.stderr | 11 | ||||
| -rw-r--r-- | tests/ui/traits/const-traits/call-const-trait-method-pass.stderr | 19 | ||||
| -rw-r--r-- | tests/ui/traits/const-traits/const-and-non-const-impl.stderr | 20 | ||||
| -rw-r--r-- | tests/ui/traits/const-traits/generic-bound.rs | 3 | ||||
| -rw-r--r-- | tests/ui/traits/const-traits/generic-bound.stderr | 20 |
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`. |
