Rollup merge of #143774 - oli-obk:const_from, r=fee1-dead

constify `From` and `Into`

tracking issue rust-lang/rust#143773

r? ``````@fee1-dead``````

I did not mark any impls elsewhere as `const`, those can happen on their own timeframe and don't need to be part of this MVP. But if there are some core ones you think should be in there I'll happily add them, just couldn't think of any
This commit is contained in:
Matthias Krüger 2025-07-13 15:16:00 +02:00 committed by GitHub
commit ccd6d6c04f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 38 additions and 43 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -1,6 +1,6 @@
//@ known-bug: #110395
#![feature(const_trait_impl, const_from)]
#![feature(const_trait_impl)]
//@ check-pass
#[const_trait]
trait Convert<T> {

View File

@ -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`.