Skip to content
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

Make some Clone impls const #91804

Merged
merged 1 commit into from
Mar 10, 2022
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
21 changes: 15 additions & 6 deletions library/core/src/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ pub trait Clone: Sized {
/// allocations.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn clone_from(&mut self, source: &Self) {
#[default_method_body_is_const]
fn clone_from(&mut self, source: &Self)
where
Self: ~const Drop,
{
*self = source.clone()
}
}
Expand Down Expand Up @@ -178,7 +182,8 @@ mod impls {
($($t:ty)*) => {
$(
#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for $t {
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
impl const Clone for $t {
#[inline]
fn clone(&self) -> Self {
*self
Expand All @@ -196,23 +201,26 @@ mod impls {
}

#[unstable(feature = "never_type", issue = "35121")]
impl Clone for ! {
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
impl const Clone for ! {
#[inline]
fn clone(&self) -> Self {
*self
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for *const T {
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
impl<T: ?Sized> const Clone for *const T {
#[inline]
fn clone(&self) -> Self {
*self
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for *mut T {
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
impl<T: ?Sized> const Clone for *mut T {
#[inline]
fn clone(&self) -> Self {
*self
Expand All @@ -221,7 +229,8 @@ mod impls {

/// Shared references can be cloned, but mutable references *cannot*!
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Clone for &T {
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
impl<T: ?Sized> const Clone for &T {
#[inline]
#[rustc_diagnostic_item = "noop_method_clone"]
fn clone(&self) -> Self {
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/convert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,8 @@ impl AsMut<str> for str {
pub enum Infallible {}

#[stable(feature = "convert_infallible", since = "1.34.0")]
impl Clone for Infallible {
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
impl const Clone for Infallible {
fn clone(&self) -> Infallible {
match *self {}
}
Expand Down
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
#![feature(const_caller_location)]
#![feature(const_cell_into_inner)]
#![feature(const_char_convert)]
#![feature(const_clone)]
#![feature(const_discriminant)]
#![feature(const_eval_select)]
#![feature(const_float_bits_conv)]
Expand Down
6 changes: 5 additions & 1 deletion library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1668,7 +1668,11 @@ const fn expect_failed(msg: &str) -> ! {
/////////////////////////////////////////////////////////////////////////////

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone> Clone for Option<T> {
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
impl<T> const Clone for Option<T>
where
T: ~const Clone + ~const Drop,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this change the way rustdoc renders it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before:
image
After:
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yea, there's a pending fix for the missing space, but the additional Drop bound is really confusing for users and we should probably figure out out story there (both for documentation and explanation) before we expose it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will all such cases need to be explained in the future? It seems a bit hard... I think it would be nice if we could switch displaying of ~const (and ~const Drop) bound...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, I'm unsure about ~const bounds in general, we should probably talk to the rustdoc team to figure out how it should display.

For ~const Drop I think we should just hide it from rustdoc. That bound is pretty much useless to see for anyone. We could potentially add a small symbol to the generic param that has a ~const Drop bound. Otherwise I fear that the useful bounds may get drowned out

Copy link
Contributor Author

@lilasta lilasta Jan 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T: ~const Drop seems to mean "T doesn't require non-const Drop to destruct the value", not "T implements ~const Drop". For example, primitive types don't implement const Drop but are destructible at compile-time. Anyway, the point is that this is mostly needed in code that destructs values at compile-time and is implemented using generics.

The determination seems to be implemented here:
https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs#L140

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T: ~const Drop seems to mean "T doesn't require non-const Drop to destruct the value"

I'm a bit confused about what you mean. Do you mean "T must be able to be Droped at compile-time"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I'm sorry for confusing you.

Copy link
Member

@camelid camelid Feb 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the ~ mean? I thought ~const meant "maybe const" rather than "definitely const", but I may have misunderstood.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means "const if whatever the bound is on is in a const context". So if it's on a generic param of a const fn, calling that const fn in a const item or other const context requires the generic param to implement the trait constly, in regular runtime code it just requires the trait to be implemented with no requirement about constness at all

{
#[inline]
fn clone(&self) -> Self {
match self {
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,8 @@ impl<T> NonNull<[T]> {
}

#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: ?Sized> Clone for NonNull<T> {
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
impl<T: ?Sized> const Clone for NonNull<T> {
#[inline]
fn clone(&self) -> Self {
*self
Expand Down
3 changes: 2 additions & 1 deletion library/core/src/ptr/unique.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ impl<T: ?Sized> Unique<T> {
}

#[unstable(feature = "ptr_internals", issue = "none")]
impl<T: ?Sized> Clone for Unique<T> {
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
impl<T: ?Sized> const Clone for Unique<T> {
#[inline]
fn clone(&self) -> Self {
*self
Expand Down
7 changes: 6 additions & 1 deletion library/core/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1665,7 +1665,12 @@ fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! {
/////////////////////////////////////////////////////////////////////////////

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone, E: Clone> Clone for Result<T, E> {
#[rustc_const_unstable(feature = "const_clone", issue = "91805")]
impl<T, E> const Clone for Result<T, E>
where
T: ~const Clone + ~const Drop,
E: ~const Clone + ~const Drop,
{
#[inline]
fn clone(&self) -> Self {
match self {
Expand Down