Skip to content

Commit 04d1bdc

Browse files
Constify Deref and DerefMut
1 parent 15b663e commit 04d1bdc

5 files changed

+60
-21
lines changed

library/core/src/ops/deref.rs

+47
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
#[doc(alias = "&*")]
134134
#[stable(feature = "rust1", since = "1.0.0")]
135135
#[rustc_diagnostic_item = "Deref"]
136+
#[cfg_attr(not(bootstrap), const_trait)]
136137
pub trait Deref {
137138
/// The resulting type after dereferencing.
138139
#[stable(feature = "rust1", since = "1.0.0")]
@@ -147,6 +148,7 @@ pub trait Deref {
147148
fn deref(&self) -> &Self::Target;
148149
}
149150

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

162+
#[cfg(not(bootstrap))]
163+
#[stable(feature = "rust1", since = "1.0.0")]
164+
impl<T: ?Sized> const Deref for &T {
165+
type Target = T;
166+
167+
#[rustc_diagnostic_item = "noop_method_deref"]
168+
fn deref(&self) -> &T {
169+
*self
170+
}
171+
}
172+
160173
#[stable(feature = "rust1", since = "1.0.0")]
161174
impl<T: ?Sized> !DerefMut for &T {}
162175

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

186+
#[cfg(not(bootstrap))]
187+
#[stable(feature = "rust1", since = "1.0.0")]
188+
impl<T: ?Sized> const Deref for &mut T {
189+
type Target = T;
190+
191+
fn deref(&self) -> &T {
192+
*self
193+
}
194+
}
195+
172196
/// Used for mutable dereferencing operations, like in `*v = 1;`.
173197
///
174198
/// In addition to being used for explicit dereferencing operations with the
@@ -258,23 +282,46 @@ impl<T: ?Sized> Deref for &mut T {
258282
/// *x = 'b';
259283
/// assert_eq!('b', x.value);
260284
/// ```
285+
#[cfg(not(bootstrap))]
286+
#[lang = "deref_mut"]
287+
#[doc(alias = "*")]
288+
#[stable(feature = "rust1", since = "1.0.0")]
289+
#[const_trait]
290+
pub trait DerefMut: ~const Deref {
291+
/// Mutably dereferences the value.
292+
#[stable(feature = "rust1", since = "1.0.0")]
293+
#[rustc_diagnostic_item = "deref_mut_method"]
294+
fn deref_mut(&mut self) -> &mut Self::Target;
295+
}
296+
297+
/// Bootstrap
261298
#[lang = "deref_mut"]
262299
#[doc(alias = "*")]
263300
#[stable(feature = "rust1", since = "1.0.0")]
301+
#[cfg(bootstrap)]
264302
pub trait DerefMut: Deref {
265303
/// Mutably dereferences the value.
266304
#[stable(feature = "rust1", since = "1.0.0")]
267305
#[rustc_diagnostic_item = "deref_mut_method"]
268306
fn deref_mut(&mut self) -> &mut Self::Target;
269307
}
270308

309+
#[cfg(bootstrap)]
271310
#[stable(feature = "rust1", since = "1.0.0")]
272311
impl<T: ?Sized> DerefMut for &mut T {
273312
fn deref_mut(&mut self) -> &mut T {
274313
*self
275314
}
276315
}
277316

317+
#[cfg(not(bootstrap))]
318+
#[stable(feature = "rust1", since = "1.0.0")]
319+
impl<T: ?Sized> const DerefMut for &mut T {
320+
fn deref_mut(&mut self) -> &mut T {
321+
*self
322+
}
323+
}
324+
278325
/// Perma-unstable marker trait. Indicates that the type has a well-behaved [`Deref`]
279326
/// (and, if applicable, [`DerefMut`]) implementation. This is relied on for soundness
280327
/// of deref patterns.

tests/ui/issues/issue-25901.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ struct A;
22
struct B;
33

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

77
use std::ops::Deref;
88

tests/ui/issues/issue-25901.stderr

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

2111
error: aborting due to 1 previous error
2212

23-
For more information about this error, try `rustc --explain E0015`.
13+
For more information about this error, try `rustc --explain E0658`.

tests/ui/self/arbitrary-self-from-method-substs-ice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ impl Foo {
1111
//~^ ERROR invalid generic `self` parameter type
1212
//~| ERROR destructor of `R` cannot be evaluated at compile-time
1313
self.0
14-
//~^ ERROR cannot call non-const fn `<R as Deref>::deref` in constant function
14+
//~^ ERROR cannot call conditionally-const method `<R as Deref>::deref` in constant function
1515
}
1616
}
1717

tests/ui/self/arbitrary-self-from-method-substs-ice.stderr

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

911
error[E0493]: destructor of `R` cannot be evaluated at compile-time
1012
--> $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 {
2628

2729
error: aborting due to 3 previous errors
2830

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

0 commit comments

Comments
 (0)