Skip to content

Commit 56c6372

Browse files
committed
Move CoercePointee to core::ops
1 parent a2db928 commit 56c6372

20 files changed

+259
-255
lines changed

compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
102102
// # Validity assertion which will be checked later in `rustc_hir_analysis::coherence::builtins`.
103103
{
104104
let trait_path =
105-
cx.path_all(span, true, path!(span, core::marker::CoercePointeeValidated), vec![]);
105+
cx.path_all(span, true, path!(span, core::ops::CoercePointeeValidated), vec![]);
106106
let trait_ref = cx.trait_ref(trait_path);
107107
push(Annotatable::Item(
108108
cx.item(

compiler/rustc_error_codes/src/error_codes/E0802.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ The target data is not a `struct`.
77

88
```compile_fail,E0802
99
#![feature(coerce_pointee)]
10-
use std::marker::CoercePointee;
10+
use std::ops::CoercePointee;
1111
#[derive(CoercePointee)]
1212
enum NotStruct<'a, T: ?Sized> {
1313
Variant(&'a T),
@@ -19,7 +19,7 @@ in other words.
1919

2020
```compile_fail,E0802
2121
#![feature(coerce_pointee)]
22-
use std::marker::CoercePointee;
22+
use std::ops::CoercePointee;
2323
#[derive(CoercePointee)]
2424
struct NotTransparent<'a, #[pointee] T: ?Sized> {
2525
ptr: &'a T,
@@ -30,7 +30,7 @@ The target data has no data field.
3030

3131
```compile_fail,E0802
3232
#![feature(coerce_pointee)]
33-
use std::marker::CoercePointee;
33+
use std::ops::CoercePointee;
3434
#[derive(CoercePointee)]
3535
#[repr(transparent)]
3636
struct NoField<'a, #[pointee] T: ?Sized> {}
@@ -40,7 +40,7 @@ The target data is not generic over any data, or has no generic type parameter.
4040

4141
```compile_fail,E0802
4242
#![feature(coerce_pointee)]
43-
use std::marker::CoercePointee;
43+
use std::ops::CoercePointee;
4444
#[derive(CoercePointee)]
4545
#[repr(transparent)]
4646
struct NoGeneric<'a>(&'a u8);
@@ -51,7 +51,7 @@ a pointee for coercion.
5151

5252
```compile_fail,E0802
5353
#![feature(coerce_pointee)]
54-
use std::marker::CoercePointee;
54+
use std::ops::CoercePointee;
5555
#[derive(CoercePointee)]
5656
#[repr(transparent)]
5757
struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> {
@@ -64,7 +64,7 @@ pointees for coercion.
6464

6565
```compile_fail,E0802
6666
#![feature(coerce_pointee)]
67-
use std::marker::CoercePointee;
67+
use std::ops::CoercePointee;
6868
#[derive(CoercePointee)]
6969
#[repr(transparent)]
7070
struct TooManyPointees<
@@ -78,7 +78,7 @@ The type parameter that is designated as a pointee is not marked `?Sized`.
7878

7979
```compile_fail,E0802
8080
#![feature(coerce_pointee)]
81-
use std::marker::CoercePointee;
81+
use std::ops::CoercePointee;
8282
#[derive(CoercePointee)]
8383
#[repr(transparent)]
8484
struct NoMaybeSized<'a, #[pointee] T> {

library/core/src/marker.rs

Lines changed: 0 additions & 210 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,213 +1131,3 @@ pub trait FnPtr: Copy + Clone {
11311131
#[lang = "fn_ptr_addr"]
11321132
fn addr(self) -> *const ();
11331133
}
1134-
1135-
/// Derive macro that makes a smart pointer usable with trait objects.
1136-
///
1137-
/// # What this macro does
1138-
///
1139-
/// This macro is intended to be used with user-defined pointer types, and makes it possible to
1140-
/// perform coercions on the pointee of the user-defined pointer. There are two aspects to this:
1141-
///
1142-
/// ## Unsizing coercions of the pointee
1143-
///
1144-
/// By using the macro, the following example will compile:
1145-
/// ```
1146-
/// #![feature(derive_coerce_pointee)]
1147-
/// use std::marker::CoercePointee;
1148-
/// use std::ops::Deref;
1149-
///
1150-
/// #[derive(CoercePointee)]
1151-
/// #[repr(transparent)]
1152-
/// struct MySmartPointer<T: ?Sized>(Box<T>);
1153-
///
1154-
/// impl<T: ?Sized> Deref for MySmartPointer<T> {
1155-
/// type Target = T;
1156-
/// fn deref(&self) -> &T {
1157-
/// &self.0
1158-
/// }
1159-
/// }
1160-
///
1161-
/// trait MyTrait {}
1162-
///
1163-
/// impl MyTrait for i32 {}
1164-
///
1165-
/// fn main() {
1166-
/// let ptr: MySmartPointer<i32> = MySmartPointer(Box::new(4));
1167-
///
1168-
/// // This coercion would be an error without the derive.
1169-
/// let ptr: MySmartPointer<dyn MyTrait> = ptr;
1170-
/// }
1171-
/// ```
1172-
/// Without the `#[derive(CoercePointee)]` macro, this example would fail with the following error:
1173-
/// ```text
1174-
/// error[E0308]: mismatched types
1175-
/// --> src/main.rs:11:44
1176-
/// |
1177-
/// 11 | let ptr: MySmartPointer<dyn MyTrait> = ptr;
1178-
/// | --------------------------- ^^^ expected `MySmartPointer<dyn MyTrait>`, found `MySmartPointer<i32>`
1179-
/// | |
1180-
/// | expected due to this
1181-
/// |
1182-
/// = note: expected struct `MySmartPointer<dyn MyTrait>`
1183-
/// found struct `MySmartPointer<i32>`
1184-
/// = help: `i32` implements `MyTrait` so you could box the found value and coerce it to the trait object `Box<dyn MyTrait>`, you will have to change the expected type as well
1185-
/// ```
1186-
///
1187-
/// ## Dyn compatibility
1188-
///
1189-
/// This macro allows you to dispatch on the user-defined pointer type. That is, traits using the
1190-
/// type as a receiver are dyn-compatible. For example, this compiles:
1191-
///
1192-
/// ```
1193-
/// #![feature(arbitrary_self_types, derive_coerce_pointee)]
1194-
/// use std::marker::CoercePointee;
1195-
/// use std::ops::Deref;
1196-
///
1197-
/// #[derive(CoercePointee)]
1198-
/// #[repr(transparent)]
1199-
/// struct MySmartPointer<T: ?Sized>(Box<T>);
1200-
///
1201-
/// impl<T: ?Sized> Deref for MySmartPointer<T> {
1202-
/// type Target = T;
1203-
/// fn deref(&self) -> &T {
1204-
/// &self.0
1205-
/// }
1206-
/// }
1207-
///
1208-
/// // You can always define this trait. (as long as you have #![feature(arbitrary_self_types)])
1209-
/// trait MyTrait {
1210-
/// fn func(self: MySmartPointer<Self>);
1211-
/// }
1212-
///
1213-
/// // But using `dyn MyTrait` requires #[derive(CoercePointee)].
1214-
/// fn call_func(value: MySmartPointer<dyn MyTrait>) {
1215-
/// value.func();
1216-
/// }
1217-
/// ```
1218-
/// If you remove the `#[derive(CoercePointee)]` annotation from the struct, then the above example
1219-
/// will fail with this error message:
1220-
/// ```text
1221-
/// error[E0038]: the trait `MyTrait` is not dyn compatible
1222-
/// --> src/lib.rs:21:36
1223-
/// |
1224-
/// 17 | fn func(self: MySmartPointer<Self>);
1225-
/// | -------------------- help: consider changing method `func`'s `self` parameter to be `&self`: `&Self`
1226-
/// ...
1227-
/// 21 | fn call_func(value: MySmartPointer<dyn MyTrait>) {
1228-
/// | ^^^^^^^^^^^ `MyTrait` is not dyn compatible
1229-
/// |
1230-
/// note: for a trait to be dyn compatible it needs to allow building a vtable
1231-
/// for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
1232-
/// --> src/lib.rs:17:19
1233-
/// |
1234-
/// 16 | trait MyTrait {
1235-
/// | ------- this trait is not dyn compatible...
1236-
/// 17 | fn func(self: MySmartPointer<Self>);
1237-
/// | ^^^^^^^^^^^^^^^^^^^^ ...because method `func`'s `self` parameter cannot be dispatched on
1238-
/// ```
1239-
///
1240-
/// # Requirements for using the macro
1241-
///
1242-
/// This macro can only be used if:
1243-
/// * The type is a `#[repr(transparent)]` struct.
1244-
/// * The type of its non-zero-sized field must either be a standard library pointer type
1245-
/// (reference, raw pointer, `NonNull`, `Box`, `Rc`, `Arc`, etc.) or another user-defined type
1246-
/// also using the `#[derive(CoercePointee)]` macro.
1247-
/// * Zero-sized fields must not mention any generic parameters unless the zero-sized field has
1248-
/// type [`PhantomData`].
1249-
///
1250-
/// ## Multiple type parameters
1251-
///
1252-
/// If the type has multiple type parameters, then you must explicitly specify which one should be
1253-
/// used for dynamic dispatch. For example:
1254-
/// ```
1255-
/// # #![feature(derive_coerce_pointee)]
1256-
/// # use std::marker::{CoercePointee, PhantomData};
1257-
/// #[derive(CoercePointee)]
1258-
/// #[repr(transparent)]
1259-
/// struct MySmartPointer<#[pointee] T: ?Sized, U> {
1260-
/// ptr: Box<T>,
1261-
/// _phantom: PhantomData<U>,
1262-
/// }
1263-
/// ```
1264-
/// Specifying `#[pointee]` when the struct has only one type parameter is allowed, but not required.
1265-
///
1266-
/// # Examples
1267-
///
1268-
/// A custom implementation of the `Rc` type:
1269-
/// ```
1270-
/// #![feature(derive_coerce_pointee)]
1271-
/// use std::marker::CoercePointee;
1272-
/// use std::ops::Deref;
1273-
/// use std::ptr::NonNull;
1274-
///
1275-
/// #[derive(CoercePointee)]
1276-
/// #[repr(transparent)]
1277-
/// pub struct Rc<T: ?Sized> {
1278-
/// inner: NonNull<RcInner<T>>,
1279-
/// }
1280-
///
1281-
/// struct RcInner<T: ?Sized> {
1282-
/// refcount: usize,
1283-
/// value: T,
1284-
/// }
1285-
///
1286-
/// impl<T: ?Sized> Deref for Rc<T> {
1287-
/// type Target = T;
1288-
/// fn deref(&self) -> &T {
1289-
/// let ptr = self.inner.as_ptr();
1290-
/// unsafe { &(*ptr).value }
1291-
/// }
1292-
/// }
1293-
///
1294-
/// impl<T> Rc<T> {
1295-
/// pub fn new(value: T) -> Self {
1296-
/// let inner = Box::new(RcInner {
1297-
/// refcount: 1,
1298-
/// value,
1299-
/// });
1300-
/// Self {
1301-
/// inner: NonNull::from(Box::leak(inner)),
1302-
/// }
1303-
/// }
1304-
/// }
1305-
///
1306-
/// impl<T: ?Sized> Clone for Rc<T> {
1307-
/// fn clone(&self) -> Self {
1308-
/// // A real implementation would handle overflow here.
1309-
/// unsafe { (*self.inner.as_ptr()).refcount += 1 };
1310-
/// Self { inner: self.inner }
1311-
/// }
1312-
/// }
1313-
///
1314-
/// impl<T: ?Sized> Drop for Rc<T> {
1315-
/// fn drop(&mut self) {
1316-
/// let ptr = self.inner.as_ptr();
1317-
/// unsafe { (*ptr).refcount -= 1 };
1318-
/// if unsafe { (*ptr).refcount } == 0 {
1319-
/// drop(unsafe { Box::from_raw(ptr) });
1320-
/// }
1321-
/// }
1322-
/// }
1323-
/// ```
1324-
#[rustc_builtin_macro(CoercePointee, attributes(pointee))]
1325-
#[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize, coerce_pointee_validated)]
1326-
#[rustc_diagnostic_item = "CoercePointee"]
1327-
#[unstable(feature = "derive_coerce_pointee", issue = "123430")]
1328-
pub macro CoercePointee($item:item) {
1329-
/* compiler built-in */
1330-
}
1331-
1332-
/// A trait that is implemented for ADTs with `derive(CoercePointee)` so that
1333-
/// the compiler can enforce the derive impls are valid post-expansion, since
1334-
/// the derive has stricter requirements than if the impls were written by hand.
1335-
///
1336-
/// This trait is not intended to be implemented by users or used other than
1337-
/// validation, so it should never be stabilized.
1338-
#[lang = "coerce_pointee_validated"]
1339-
#[unstable(feature = "coerce_pointee_validated", issue = "none")]
1340-
#[doc(hidden)]
1341-
pub trait CoercePointeeValidated {
1342-
/* compiler built-in */
1343-
}

library/core/src/ops/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ pub use self::try_trait::Yeet;
199199
pub(crate) use self::try_trait::{ChangeOutputType, NeverShortCircuit};
200200
#[unstable(feature = "try_trait_v2", issue = "84277", old_name = "try_trait")]
201201
pub use self::try_trait::{FromResidual, Try};
202+
#[unstable(feature = "derive_coerce_pointee", issue = "123430")]
203+
pub use self::unsize::CoercePointee;
204+
#[unstable(feature = "coerce_pointee_validated", issue = "none")]
205+
pub use self::unsize::CoercePointeeValidated;
202206
#[unstable(feature = "coerce_unsized", issue = "18598")]
203207
pub use self::unsize::CoerceUnsized;
204208
#[unstable(feature = "dispatch_from_dyn", issue = "none")]

0 commit comments

Comments
 (0)