about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/ops/deref.rs47
-rw-r--r--tests/ui/issues/issue-25901.rs2
-rw-r--r--tests/ui/issues/issue-25901.stderr20
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs-ice.rs2
-rw-r--r--tests/ui/self/arbitrary-self-from-method-substs-ice.stderr10
5 files changed, 60 insertions, 21 deletions
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
index 45688727c9b..e9bb40d0fdd 100644
--- a/library/core/src/ops/deref.rs
+++ b/library/core/src/ops/deref.rs
@@ -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")]
@@ -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;
@@ -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;
@@ -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
@@ -258,9 +282,23 @@ 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")]
@@ -268,6 +306,7 @@ pub trait DerefMut: Deref {
     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 {
@@ -275,6 +314,14 @@ impl<T: ?Sized> DerefMut for &mut T {
     }
 }
 
+#[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.
diff --git a/tests/ui/issues/issue-25901.rs b/tests/ui/issues/issue-25901.rs
index 85e12463a90..eae038c71a0 100644
--- a/tests/ui/issues/issue-25901.rs
+++ b/tests/ui/issues/issue-25901.rs
@@ -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;
 
diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr
index bcbc805908f..655a8b78c6a 100644
--- a/tests/ui/issues/issue-25901.stderr
+++ b/tests/ui/issues/issue-25901.stderr
@@ -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`.
diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
index d121a194be6..2c0f25fc6ff 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
+++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.rs
@@ -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
     }
 }
 
diff --git a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
index 7252b5890fd..cf4c219215e 100644
--- a/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
+++ b/tests/ui/self/arbitrary-self-from-method-substs-ice.stderr
@@ -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
@@ -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`.