Skip to content

constify From and Into #143774

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions library/core/src/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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"]
Expand Down Expand Up @@ -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")]
Expand Down Expand Up @@ -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")]
Expand Down Expand Up @@ -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)`.
///
Expand All @@ -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 {
Expand All @@ -787,17 +797,19 @@ 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
}
}

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

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

Expand Down
9 changes: 9 additions & 0 deletions tests/ui/specialization/issue-111232.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
9 changes: 6 additions & 3 deletions tests/ui/specialization/issue-111232.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@ known-bug: #110395
#![feature(const_trait_impl, const_from)]

#![feature(const_trait_impl)]
//@ check-pass

#[const_trait]
trait Convert<T> {
Expand Down

This file was deleted.

Loading