diff options
| author | Oli Scherer <github333195615777966@oli-obk.de> | 2025-07-11 08:17:58 +0000 |
|---|---|---|
| committer | Oli Scherer <github333195615777966@oli-obk.de> | 2025-07-11 08:30:47 +0000 |
| commit | e681d1a9731897951ea4c2d68c7d8f4a322b9904 (patch) | |
| tree | f00d1498a1fb2b091815fae9c2340c079b97e773 | |
| parent | cdac44e608c3df9a241e0a1b53b3f62af250dbf1 (diff) | |
| download | rust-e681d1a9731897951ea4c2d68c7d8f4a322b9904.tar.gz rust-e681d1a9731897951ea4c2d68c7d8f4a322b9904.zip | |
constify `From` and `Into`
5 files changed, 38 insertions, 43 deletions
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 7132e712ec5..38381dbdf23 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -445,6 +445,8 @@ pub trait AsMut<T: PointeeSized>: PointeeSized { #[rustc_diagnostic_item = "Into"] #[stable(feature = "rust1", since = "1.0.0")] #[doc(search_unbox)] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait Into<T>: Sized { /// Converts this type into the (usually inferred) input type. #[must_use] @@ -580,6 +582,8 @@ pub trait Into<T>: Sized { note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix", ))] #[doc(search_unbox)] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait From<T>: Sized { /// Converts to this type from the input type. #[rustc_diagnostic_item = "from_fn"] @@ -607,6 +611,8 @@ pub trait From<T>: Sized { /// [`Into`], see there for details. #[rustc_diagnostic_item = "TryInto"] #[stable(feature = "try_from", since = "1.34.0")] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait TryInto<T>: Sized { /// The type returned in the event of a conversion error. #[stable(feature = "try_from", since = "1.34.0")] @@ -685,6 +691,8 @@ pub trait TryInto<T>: Sized { /// [`try_from`]: TryFrom::try_from #[rustc_diagnostic_item = "TryFrom"] #[stable(feature = "try_from", since = "1.34.0")] +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +#[const_trait] pub trait TryFrom<T>: Sized { /// The type returned in the event of a conversion error. #[stable(feature = "try_from", since = "1.34.0")] @@ -754,9 +762,10 @@ where // From implies Into #[stable(feature = "rust1", since = "1.0.0")] -impl<T, U> Into<U> for T +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl<T, U> const Into<U> for T where - U: From<T>, + U: ~const From<T>, { /// Calls `U::from(self)`. /// @@ -771,7 +780,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_from", issue = "143773")] +impl<T> const From<T> for T { /// Returns the argument unchanged. #[inline(always)] fn from(t: T) -> T { @@ -787,7 +797,8 @@ impl<T> From<T> for T { #[stable(feature = "convert_infallible", since = "1.34.0")] #[rustc_reservation_impl = "permitting this impl would forbid us from adding \ `impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"] -impl<T> From<!> for T { +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl<T> const From<!> for T { fn from(t: !) -> T { t } @@ -795,9 +806,10 @@ impl<T> From<!> for T { // TryFrom implies TryInto #[stable(feature = "try_from", since = "1.34.0")] -impl<T, U> TryInto<U> for T +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl<T, U> const TryInto<U> for T where - U: TryFrom<T>, + U: ~const TryFrom<T>, { type Error = U::Error; @@ -810,9 +822,10 @@ where // Infallible conversions are semantically equivalent to fallible conversions // with an uninhabited error type. #[stable(feature = "try_from", since = "1.34.0")] -impl<T, U> TryFrom<U> for T +#[rustc_const_unstable(feature = "const_from", issue = "143773")] +impl<T, U> const TryFrom<U> for T where - U: Into<T>, + U: ~const Into<T>, { type Error = Infallible; diff --git a/tests/ui/specialization/issue-111232.rs b/tests/ui/specialization/issue-111232.rs index 3ed3c580e6d..fa00f01886f 100644 --- a/tests/ui/specialization/issue-111232.rs +++ b/tests/ui/specialization/issue-111232.rs @@ -1,4 +1,13 @@ #![feature(min_specialization)] +#![feature(const_trait_impl)] + +trait From<T> { + fn from(t: T) -> Self; +} + +impl<T> From<T> for T { + fn from(t: T) -> T { t } +} struct S; diff --git a/tests/ui/specialization/issue-111232.stderr b/tests/ui/specialization/issue-111232.stderr index ed392e4f915..5f169f0bb36 100644 --- a/tests/ui/specialization/issue-111232.stderr +++ b/tests/ui/specialization/issue-111232.stderr @@ -1,10 +1,13 @@ error[E0520]: `from` specializes an item from a parent `impl`, but that item is not marked `default` - --> $DIR/issue-111232.rs:6:5 + --> $DIR/issue-111232.rs:15:5 | +LL | impl<T> From<T> for T { + | --------------------- parent `impl` is here +... LL | fn from(s: S) -> S { - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ cannot specialize default item `from` | - = note: parent implementation is in crate `core` + = note: to specialize, `from` in the parent `impl` must be marked `default` error: aborting due to 1 previous error diff --git a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs index 86e3e5f769f..d5f80acc15b 100644 --- a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs +++ b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.rs @@ -1,6 +1,6 @@ -//@ known-bug: #110395 +#![feature(const_trait_impl, const_from)] -#![feature(const_trait_impl)] +//@ check-pass #[const_trait] trait Convert<T> { diff --git a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr b/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr deleted file mode 100644 index e7f10e73c69..00000000000 --- a/tests/ui/traits/const-traits/non-const-op-in-closure-in-const.stderr +++ /dev/null @@ -1,30 +0,0 @@ -error: `[const]` can only be applied to `#[const_trait]` traits - --> $DIR/non-const-op-in-closure-in-const.rs:10:44 - | -LL | impl<A, B> const Convert<B> for A where B: [const] From<A> { - | ^^^^^^^ can't be applied to `From` - | -note: `From` can't be used with `[const]` because it isn't annotated with `#[const_trait]` - --> $SRC_DIR/core/src/convert/mod.rs:LL:COL - -error: `[const]` can only be applied to `#[const_trait]` traits - --> $DIR/non-const-op-in-closure-in-const.rs:10:44 - | -LL | impl<A, B> const Convert<B> for A where B: [const] From<A> { - | ^^^^^^^ can't be applied to `From` - | -note: `From` can't be used with `[const]` because it isn't annotated with `#[const_trait]` - --> $SRC_DIR/core/src/convert/mod.rs:LL:COL - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error[E0015]: cannot call non-const associated function `<B as From<A>>::from` in constant functions - --> $DIR/non-const-op-in-closure-in-const.rs:12:9 - | -LL | B::from(self) - | ^^^^^^^^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0015`. |
