Skip to content

Commit

Permalink
Constify Deref and DerefMut
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Nov 20, 2024
1 parent 8574982 commit 8231957
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 21 deletions.
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
#![feature(const_is_char_boundary)]
#![feature(const_precise_live_drops)]
#![feature(const_str_split_at)]
#![feature(const_trait_impl)]
#![feature(decl_macro)]
#![feature(deprecated_suggestion)]
#![feature(doc_cfg)]
Expand Down
47 changes: 47 additions & 0 deletions library/core/src/ops/deref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
#[doc(alias = "&*")]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "Deref"]
#[cfg_attr(not(bootstrap), const_trait)]
pub trait Deref {
/// The resulting type after dereferencing.
#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -147,6 +148,7 @@ pub trait Deref {
fn deref(&self) -> &Self::Target;
}

#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for &T {
type Target = T;
Expand All @@ -157,9 +159,21 @@ impl<T: ?Sized> Deref for &T {
}
}

#[cfg(not(bootstrap))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> const Deref for &T {
type Target = T;

#[rustc_diagnostic_item = "noop_method_deref"]
fn deref(&self) -> &T {
*self
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> !DerefMut for &T {}

#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for &mut T {
type Target = T;
Expand All @@ -169,6 +183,16 @@ impl<T: ?Sized> Deref for &mut T {
}
}

#[cfg(not(bootstrap))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> const Deref for &mut T {
type Target = T;

fn deref(&self) -> &T {
*self
}
}

/// Used for mutable dereferencing operations, like in `*v = 1;`.
///
/// In addition to being used for explicit dereferencing operations with the
Expand Down Expand Up @@ -258,23 +282,46 @@ impl<T: ?Sized> Deref for &mut T {
/// *x = 'b';
/// assert_eq!('b', x.value);
/// ```
#[cfg(not(bootstrap))]
#[lang = "deref_mut"]
#[doc(alias = "*")]
#[stable(feature = "rust1", since = "1.0.0")]
#[const_trait]
pub trait DerefMut: ~const Deref {
/// Mutably dereferences the value.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "deref_mut_method"]
fn deref_mut(&mut self) -> &mut Self::Target;
}

/// Bootstrap
#[lang = "deref_mut"]
#[doc(alias = "*")]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(bootstrap)]
pub trait DerefMut: Deref {
/// Mutably dereferences the value.
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "deref_mut_method"]
fn deref_mut(&mut self) -> &mut Self::Target;
}

#[cfg(bootstrap)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> DerefMut for &mut T {
fn deref_mut(&mut self) -> &mut T {
*self
}
}

#[cfg(not(bootstrap))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> const DerefMut for &mut T {
fn deref_mut(&mut self) -> &mut T {
*self
}
}

/// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`]
/// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness
/// of deref patterns.
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-25901.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ struct A;
struct B;

static S: &'static B = &A;
//~^ ERROR cannot perform deref coercion
//~^ ERROR cannot call conditionally-const method

use std::ops::Deref;

Expand Down
20 changes: 5 additions & 15 deletions tests/ui/issues/issue-25901.stderr
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
error[E0015]: cannot perform deref coercion on `A` in statics
error[E0658]: cannot call conditionally-const method `<A as Deref>::deref` in statics
--> $DIR/issue-25901.rs:4:24
|
LL | static S: &'static B = &A;
| ^^
|
= note: attempting to deref into `B`
note: deref defined here
--> $DIR/issue-25901.rs:10:5
|
LL | type Target = B;
| ^^^^^^^^^^^
note: impl defined here, but it is not `const`
--> $DIR/issue-25901.rs:9:1
|
LL | impl Deref for A {
| ^^^^^^^^^^^^^^^^
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
= note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0658`.
2 changes: 1 addition & 1 deletion tests/ui/self/arbitrary-self-from-method-substs-ice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ impl Foo {
//~^ ERROR invalid generic `self` parameter type
//~| ERROR destructor of `R` cannot be evaluated at compile-time
self.0
//~^ ERROR cannot call non-const fn `<R as Deref>::deref` in constant function
//~^ ERROR cannot call conditionally-const method `<R as Deref>::deref` in constant function
}
}

Expand Down
10 changes: 6 additions & 4 deletions tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
error[E0015]: cannot call non-const fn `<R as Deref>::deref` in constant functions
error[E0658]: cannot call conditionally-const method `<R as Deref>::deref` in constant functions
--> $DIR/arbitrary-self-from-method-substs-ice.rs:13:9
|
LL | self.0
| ^^^^^^
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error[E0493]: destructor of `R` cannot be evaluated at compile-time
--> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43
Expand All @@ -26,5 +28,5 @@ LL | const fn get<R: Deref<Target = Self>>(self: R) -> u32 {

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0015, E0493, E0801.
For more information about an error, try `rustc --explain E0015`.
Some errors have detailed explanations: E0493, E0658, E0801.
For more information about an error, try `rustc --explain E0493`.

0 comments on commit 8231957

Please sign in to comment.