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
This commit is contained in:
commit
75b8f433e3
9 changed files with 21 additions and 79 deletions
|
@ -590,16 +590,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) {
|
fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) {
|
||||||
// if the const impl is derived using the `derive_const` attribute,
|
let is_const = self.tcx.is_const_fn(def_id.to_def_id());
|
||||||
// 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());
|
|
||||||
|
|
||||||
// Reachable const fn must have a stability attribute.
|
// Reachable const fn must have a stability attribute.
|
||||||
if is_const
|
if is_const
|
||||||
|
|
|
@ -174,6 +174,7 @@
|
||||||
#![feature(const_is_char_boundary)]
|
#![feature(const_is_char_boundary)]
|
||||||
#![feature(const_precise_live_drops)]
|
#![feature(const_precise_live_drops)]
|
||||||
#![feature(const_str_split_at)]
|
#![feature(const_str_split_at)]
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![feature(deprecated_suggestion)]
|
#![feature(deprecated_suggestion)]
|
||||||
#![feature(doc_cfg)]
|
#![feature(doc_cfg)]
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
append_const_msg
|
append_const_msg
|
||||||
)]
|
)]
|
||||||
#[doc(alias = "+")]
|
#[doc(alias = "+")]
|
||||||
|
#[cfg_attr(not(bootstrap), const_trait)]
|
||||||
pub trait Add<Rhs = Self> {
|
pub trait Add<Rhs = Self> {
|
||||||
/// The resulting type after applying the `+` operator.
|
/// The resulting type after applying the `+` operator.
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
@ -94,6 +95,7 @@ pub trait Add<Rhs = Self> {
|
||||||
macro_rules! add_impl {
|
macro_rules! add_impl {
|
||||||
($($t:ty)*) => ($(
|
($($t:ty)*) => ($(
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[cfg(bootstrap)]
|
||||||
impl Add for $t {
|
impl Add for $t {
|
||||||
type Output = $t;
|
type Output = $t;
|
||||||
|
|
||||||
|
@ -103,6 +105,17 @@ macro_rules! add_impl {
|
||||||
fn add(self, other: $t) -> $t { self + other }
|
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 }
|
forward_ref_binop! { impl Add, add for $t, $t }
|
||||||
)*)
|
)*)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub trait Bar {
|
||||||
}
|
}
|
||||||
#[stable(feature = "stable", since = "1.0.0")]
|
#[stable(feature = "stable", since = "1.0.0")]
|
||||||
impl const Bar for Foo {
|
impl const Bar for Foo {
|
||||||
//~^ ERROR implementation has missing const stability attribute
|
// ok because all users must enable `const_trait_impl`
|
||||||
fn fun() {}
|
fn fun() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,6 @@ error: function has missing const stability attribute
|
||||||
LL | pub const fn foo() {}
|
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
|
error: function has missing const stability attribute
|
||||||
--> $DIR/missing-const-stability.rs:36:1
|
--> $DIR/missing-const-stability.rs:36:1
|
||||||
|
|
|
|
||||||
|
@ -25,5 +16,5 @@ error: associated function has missing const stability attribute
|
||||||
LL | pub const fn foo() {}
|
LL | pub const fn foo() {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -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]`
|
error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
|
||||||
--> $DIR/call-const-trait-method-pass.rs:15:12
|
--> $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: 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
|
= 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
|
error[E0015]: cannot call non-const fn `<Int as PartialEq>::eq` in constant functions
|
||||||
--> $DIR/call-const-trait-method-pass.rs:20:15
|
--> $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
|
= 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`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -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`
|
error[E0119]: conflicting implementations of trait `Add` for type `Int`
|
||||||
--> $DIR/const-and-non-const-impl.rs:23:1
|
--> $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: 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
|
= 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.
|
Some errors have detailed explanations: E0117, E0119.
|
||||||
For more information about an error, try `rustc --explain E0117`.
|
For more information about an error, try `rustc --explain E0117`.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//@ known-bug: #110395
|
//@ check-pass
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
@ -26,5 +26,6 @@ const fn twice<T: std::ops::Add>(arg: S<T>) -> S<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
const _: S<i32> = twice(S(PhantomData));
|
||||||
let _ = twice(S(PhantomData::<i32>));
|
let _ = twice(S(PhantomData::<i32>));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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`.
|
|
Loading…
Add table
Add a link
Reference in a new issue