Skip to content

Commit

Permalink
s/SmartPointer/CoerceReferent/g
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Oct 5, 2024
1 parent 5a4ee43 commit a761a7b
Show file tree
Hide file tree
Showing 22 changed files with 216 additions and 215 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ macro_rules! path {
($span:expr, $($part:ident)::*) => { vec![$(Ident::new(sym::$part, $span),)*] }
}

pub(crate) fn expand_deriving_smart_ptr(
pub(crate) fn expand_deriving_coerce_referent(
cx: &ExtCtxt<'_>,
span: Span,
_mitem: &MetaItem,
Expand All @@ -37,7 +37,7 @@ pub(crate) fn expand_deriving_smart_ptr(
cx.dcx()
.struct_span_err(
span,
"`SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`",
"`CoerceReferent` can only be derived on `struct`s with `#[repr(transparent)]`",
)
.emit();
return;
Expand All @@ -50,7 +50,7 @@ pub(crate) fn expand_deriving_smart_ptr(
cx.dcx()
.struct_span_err(
span,
"`SmartPointer` can only be derived on `struct`s with at least one field",
"`CoerceReferent` can only be derived on `struct`s with at least one field",
)
.emit();
return;
Expand All @@ -60,7 +60,7 @@ pub(crate) fn expand_deriving_smart_ptr(
cx.dcx()
.struct_span_err(
span,
"`SmartPointer` can only be derived on `struct`s with `#[repr(transparent)]`",
"`CoerceReferent` can only be derived on `struct`s with `#[repr(transparent)]`",
)
.emit();
return;
Expand All @@ -82,42 +82,42 @@ pub(crate) fn expand_deriving_smart_ptr(
.enumerate()
.filter_map(|(idx, p)| {
if let GenericParamKind::Type { .. } = p.kind {
Some((idx, p.span(), p.attrs().iter().any(|attr| attr.has_name(sym::pointee))))
Some((idx, p.span(), p.attrs().iter().any(|attr| attr.has_name(sym::referent))))
} else {
None
}
})
.collect();

let pointee_param_idx = if type_params.is_empty() {
// `#[derive(SmartPointer)]` requires at least one generic type on the target `struct`
let referent_param_idx = if type_params.is_empty() {
// `#[derive(CoerceReferent)]` requires at least one generic type on the target `struct`
cx.dcx().struct_span_err(
span,
"`SmartPointer` can only be derived on `struct`s that are generic over at least one type",
"`CoerceReferent` can only be derived on `struct`s that are generic over at least one type",
).emit();
return;
} else if type_params.len() == 1 {
// Regardless of the only type param being designed as `#[pointee]` or not, we can just use it as such
// Regardless of the only type param being designed as `#[referent]` or not, we can just use it as such
type_params[0].0
} else {
let mut pointees = type_params
let mut referents = type_params
.iter()
.filter_map(|&(idx, span, is_pointee)| is_pointee.then_some((idx, span)))
.filter_map(|&(idx, span, is_referent)| is_referent.then_some((idx, span)))
.fuse();
match (pointees.next(), pointees.next()) {
match (referents.next(), referents.next()) {
(Some((idx, _span)), None) => idx,
(None, _) => {
cx.dcx().struct_span_err(
span,
"exactly one generic type parameter must be marked as #[pointee] to derive SmartPointer traits",
"exactly one generic type parameter must be marked as #[referent] to derive CoerceReferent traits",
).emit();
return;
}
(Some((_, one)), Some((_, another))) => {
cx.dcx()
.struct_span_err(
vec![one, another],
"only one type parameter can be marked as `#[pointee]` when deriving SmartPointer traits",
"only one type parameter can be marked as `#[referent]` when deriving CoerceReferent traits",
)
.emit();
return;
Expand Down Expand Up @@ -155,53 +155,53 @@ pub(crate) fn expand_deriving_smart_ptr(
push(Annotatable::Item(item));
};

// Create unsized `self`, that is, one where the `#[pointee]` type arg is replaced with `__S`. For
// Create unsized `self`, that is, one where the `#[referent]` type arg is replaced with `__S`. For
// example, instead of `MyType<'a, T>`, it will be `MyType<'a, __S>`.
let s_ty = cx.ty_ident(span, Ident::new(sym::__S, span));
let mut alt_self_params = self_params;
alt_self_params[pointee_param_idx] = GenericArg::Type(s_ty.clone());
alt_self_params[referent_param_idx] = GenericArg::Type(s_ty.clone());
let alt_self_type = cx.ty_path(cx.path_all(span, false, vec![name_ident], alt_self_params));

// # Add `Unsize<__S>` bound to `#[pointee]` at the generic parameter location
// # Add `Unsize<__S>` bound to `#[referent]` at the generic parameter location
//
// Find the `#[pointee]` parameter and add an `Unsize<__S>` bound to it.
// Find the `#[referent]` parameter and add an `Unsize<__S>` bound to it.
let mut impl_generics = generics.clone();
let pointee_ty_ident = generics.params[pointee_param_idx].ident;
let referent_ty_ident = generics.params[referent_param_idx].ident;
let mut self_bounds;
{
let pointee = &mut impl_generics.params[pointee_param_idx];
self_bounds = pointee.bounds.clone();
let referent = &mut impl_generics.params[referent_param_idx];
self_bounds = referent.bounds.clone();
if !contains_maybe_sized_bound(&self_bounds)
&& !contains_maybe_sized_bound_on_pointee(
&& !contains_maybe_sized_bound_on_referent(
&generics.where_clause.predicates,
pointee_ty_ident.name,
referent_ty_ident.name,
)
{
cx.dcx()
.struct_span_err(
pointee_ty_ident.span,
referent_ty_ident.span,
format!(
"`derive(SmartPointer)` requires {} to be marked `?Sized`",
pointee_ty_ident.name
"`derive(CoerceReferent)` requires {} to be marked `?Sized`",
referent_ty_ident.name
),
)
.emit();
return;
}
let arg = GenericArg::Type(s_ty.clone());
let unsize = cx.path_all(span, true, path!(span, core::marker::Unsize), vec![arg]);
pointee.bounds.push(cx.trait_bound(unsize, false));
// Drop `#[pointee]` attribute since it should not be recognized outside `derive(SmartPointer)`
pointee.attrs.retain(|attr| !attr.has_name(sym::pointee));
referent.bounds.push(cx.trait_bound(unsize, false));
// Drop `#[referent]` attribute since it should not be recognized outside `derive(CoerceReferent)`
referent.attrs.retain(|attr| !attr.has_name(sym::referent));
}

// # Rewrite generic parameter bounds
// For each bound `U: ..` in `struct<U: ..>`, make a new bound with `__S` in place of `#[pointee]`
// For each bound `U: ..` in `struct<U: ..>`, make a new bound with `__S` in place of `#[referent]`
// Example:
// ```
// struct<
// U: Trait<T>,
// #[pointee] T: Trait<T> + ?Sized,
// #[referent] T: Trait<T> + ?Sized,
// V: Trait<T>> ...
// ```
// ... generates this `impl` generic parameters
Expand All @@ -224,22 +224,22 @@ pub(crate) fn expand_deriving_smart_ptr(
ast::GenericParamKind::Type { default } => *default = None,
ast::GenericParamKind::Lifetime => {}
}
// We CANNOT rewrite `#[pointee]` type parameter bounds.
// We CANNOT rewrite `#[referent]` type parameter bounds.
// This has been set in stone. (**)
// So we skip over it.
// Otherwise, we push extra bounds involving `__S`.
if idx != pointee_param_idx {
if idx != referent_param_idx {
for bound in &orig_params.bounds {
let mut bound = bound.clone();
let mut substitution = TypeSubstitution {
from_name: pointee_ty_ident.name,
from_name: referent_ty_ident.name,
to_ty: &s_ty,
rewritten: false,
};
substitution.visit_param_bound(&mut bound, BoundKind::Bound);
if substitution.rewritten {
// We found use of `#[pointee]` somewhere,
// so we make a new bound using `__S` in place of `#[pointee]`
// We found use of `#[referent]` somewhere,
// so we make a new bound using `__S` in place of `#[referent]`
params.bounds.push(bound);
}
}
Expand All @@ -249,10 +249,10 @@ pub(crate) fn expand_deriving_smart_ptr(
// # Insert `__S` type parameter
//
// We now insert `__S` with the missing bounds marked with (*) above.
// We should also write the bounds from `#[pointee]` to `__S` as required by `Unsize<__S>`.
// We should also write the bounds from `#[referent]` to `__S` as required by `Unsize<__S>`.
{
let mut substitution =
TypeSubstitution { from_name: pointee_ty_ident.name, to_ty: &s_ty, rewritten: false };
TypeSubstitution { from_name: referent_ty_ident.name, to_ty: &s_ty, rewritten: false };
for bound in &mut self_bounds {
substitution.visit_param_bound(bound, BoundKind::Bound);
}
Expand All @@ -263,7 +263,7 @@ pub(crate) fn expand_deriving_smart_ptr(
// Move on to `where` clauses.
// Example:
// ```
// struct MyPointer<#[pointee] T, ..>
// struct MyPointer<#[referent] T, ..>
// where
// U: Trait<V> + Trait<T>,
// Companion<T>: Trait<T>,
Expand All @@ -282,12 +282,12 @@ pub(crate) fn expand_deriving_smart_ptr(
// __S: Trait<__S> + ?Sized,
// ```
//
// We should also write a few new `where` bounds from `#[pointee] T` to `__S`
// as well as any bound that indirectly involves the `#[pointee] T` type.
// We should also write a few new `where` bounds from `#[referent] T` to `__S`
// as well as any bound that indirectly involves the `#[referent] T` type.
for bound in &generics.where_clause.predicates {
if let ast::WherePredicate::BoundPredicate(bound) = bound {
let mut substitution = TypeSubstitution {
from_name: pointee_ty_ident.name,
from_name: referent_ty_ident.name,
to_ty: &s_ty,
rewritten: false,
};
Expand All @@ -305,18 +305,18 @@ pub(crate) fn expand_deriving_smart_ptr(
}

let extra_param = cx.typaram(span, Ident::new(sym::__S, span), self_bounds, None);
impl_generics.params.insert(pointee_param_idx + 1, extra_param);
impl_generics.params.insert(referent_param_idx + 1, extra_param);

// Add the impl blocks for `DispatchFromDyn` and `CoerceUnsized`.
let gen_args = vec![GenericArg::Type(alt_self_type.clone())];
add_impl_block(impl_generics.clone(), sym::DispatchFromDyn, gen_args.clone());
add_impl_block(impl_generics.clone(), sym::CoerceUnsized, gen_args);
}

fn contains_maybe_sized_bound_on_pointee(predicates: &[WherePredicate], pointee: Symbol) -> bool {
fn contains_maybe_sized_bound_on_referent(predicates: &[WherePredicate], referent: Symbol) -> bool {
for bound in predicates {
if let ast::WherePredicate::BoundPredicate(bound) = bound
&& bound.bounded_ty.kind.is_simple_path().is_some_and(|name| name == pointee)
&& bound.bounded_ty.kind.is_simple_path().is_some_and(|name| name == referent)
{
for bound in &bound.bounds {
if is_maybe_sized_bound(bound) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ macro path_std($($x:tt)*) {

pub(crate) mod bounds;
pub(crate) mod clone;
pub(crate) mod coerce_referent;
pub(crate) mod debug;
pub(crate) mod decodable;
pub(crate) mod default;
pub(crate) mod encodable;
pub(crate) mod hash;
pub(crate) mod smart_ptr;

#[path = "cmp/eq.rs"]
pub(crate) mod eq;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
PartialOrd: partial_ord::expand_deriving_partial_ord,
RustcDecodable: decodable::expand_deriving_rustc_decodable,
RustcEncodable: encodable::expand_deriving_rustc_encodable,
SmartPointer: smart_ptr::expand_deriving_smart_ptr,
CoerceReferent: coerce_referent::expand_deriving_coerce_referent,
}

let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,8 @@ declare_features! (
(unstable, deprecated_suggestion, "1.61.0", Some(94785)),
/// Allows deref patterns.
(incomplete, deref_patterns, "1.79.0", Some(87121)),
/// Allows deriving `SmartPointer` traits
(unstable, derive_smart_pointer, "1.79.0", Some(123430)),
/// Allows deriving `CoerceReferent` traits
(unstable, derive_coerce_referent, "1.79.0", Some(123430)),
/// Controls errors in trait implementations.
(unstable, do_not_recommend, "1.67.0", Some(51992)),
/// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::cfg_attr
// need to be fixed
| sym::cfi_encoding // FIXME(cfi_encoding)
| sym::pointee // FIXME(derive_smart_pointer)
| sym::referent // FIXME(derive_coerce_referent)
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
| sym::used // handled elsewhere to restrict to static items
| sym::repr // handled elsewhere to restrict to type decls items
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ symbols! {
Center,
Cleanup,
Clone,
CoerceReferent,
CoerceUnsized,
Command,
ConstParamTy,
Expand Down Expand Up @@ -315,7 +316,6 @@ symbols! {
Sized,
SliceIndex,
SliceIter,
SmartPointer,
Some,
SpanCtxt,
String,
Expand Down Expand Up @@ -737,9 +737,9 @@ symbols! {
deref_pure,
deref_target,
derive,
derive_coerce_referent,
derive_const,
derive_default_enum,
derive_smart_pointer,
destruct,
destructuring_assignment,
diagnostic,
Expand Down Expand Up @@ -1460,7 +1460,6 @@ symbols! {
plugin,
plugin_registrar,
plugins,
pointee,
pointee_trait,
pointer,
pointer_like,
Expand Down Expand Up @@ -1571,6 +1570,7 @@ symbols! {
ref_pat_everywhere,
ref_unwind_safe_trait,
reference,
referent,
reflect,
reg,
reg16,
Expand Down
7 changes: 4 additions & 3 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,10 +1062,11 @@ pub trait FnPtr: Copy + Clone {
}

/// Derive macro generating impls of traits related to smart pointers.
#[rustc_builtin_macro(SmartPointer, attributes(pointee))]
#[rustc_builtin_macro(CoerceReferent, attributes(referent))]
#[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize)]
#[unstable(feature = "derive_smart_pointer", issue = "123430")]
pub macro SmartPointer($item:item) {
#[unstable(feature = "derive_coerce_referent", issue = "123430")]
#[cfg(not(bootstrap))]
pub macro CoerceReferent($item:item) {
/* compiler built-in */
}

Expand Down
8 changes: 4 additions & 4 deletions tests/ui/deriving/auxiliary/another-proc-macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

extern crate proc_macro;

use proc_macro::{quote, TokenStream};
use proc_macro::{TokenStream, quote};

#[proc_macro_derive(AnotherMacro, attributes(pointee))]
#[proc_macro_derive(AnotherMacro, attributes(referent))]
pub fn derive(_input: TokenStream) -> TokenStream {
quote! {
const _: () = {
Expand All @@ -19,13 +19,13 @@ pub fn derive(_input: TokenStream) -> TokenStream {
}

#[proc_macro_attribute]
pub fn pointee(
pub fn referent(
_attr: proc_macro::TokenStream,
_item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
quote! {
const _: () = {
const POINTEE_MACRO_ATTR_DERIVED: () = ();
const REFERENT_MACRO_ATTR_DERIVED: () = ();
};
}
.into()
Expand Down
Loading

0 comments on commit a761a7b

Please sign in to comment.