Skip to content

Commit

Permalink
encode pointee type info and deduplicate errors
Browse files Browse the repository at this point in the history
  • Loading branch information
dingxiangfei2009 committed Feb 9, 2025
1 parent b943505 commit e55e437
Show file tree
Hide file tree
Showing 22 changed files with 744 additions and 72 deletions.
23 changes: 19 additions & 4 deletions compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_ast::mut_visit::MutVisitor;
use rustc_ast::visit::BoundKind;
use rustc_ast::{
self as ast, GenericArg, GenericBound, GenericParamKind, Generics, ItemKind, MetaItem,
TraitBoundModifiers, VariantData, WherePredicate,
TraitBoundModifiers, TyAlias, VariantData, WherePredicate,
};
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_errors::E0802;
Expand Down Expand Up @@ -92,6 +92,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
}
}
};
let pointee_ty_ident = generics.params[pointee_param_idx].ident;

// Create the type of `self`.
let path = cx.path_all(span, false, vec![name_ident], self_params.clone());
Expand All @@ -100,11 +101,26 @@ pub(crate) fn expand_deriving_coerce_pointee(
// Declare helper function that adds implementation blocks.
// FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls
let attrs = thin_vec![cx.attr_word(sym::automatically_derived, span),];
// # Validity assertion which will be checked later in `rustc_hir_analysis::coherence::builtins`.
// # Validity assertion
// This will be checked later in `rustc_hir_analysis::coherence::builtins`.
{
let trait_path =
cx.path_all(span, true, path!(span, core::marker::CoercePointeeValidated), vec![]);
let trait_ref = cx.trait_ref(trait_path);
let pointee_assoc_item = cx.assoc_item(
span,
Ident::new(sym::Pointee, span),
thin_vec![],
ast::AssocItemKind::Type(Box::new(TyAlias {
defaultness: ast::Defaultness::Final,
generics: ast::Generics::default(),
where_clauses: ast::TyAliasWhereClauses::default(),
bounds: vec![],
ty: Some(
cx.ty(span, ast::TyKind::Path(None, cx.path_ident(span, pointee_ty_ident))),
),
})),
);
push(Annotatable::Item(
cx.item(
span,
Expand Down Expand Up @@ -141,7 +157,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
},
of_trait: Some(trait_ref),
self_ty: self_type.clone(),
items: ThinVec::new(),
items: thin_vec![pointee_assoc_item],
})),
),
));
Expand Down Expand Up @@ -180,7 +196,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
//
// Find the `#[pointee]` 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 mut self_bounds;
{
let pointee = &mut impl_generics.params[pointee_param_idx];
Expand Down
22 changes: 22 additions & 0 deletions compiler/rustc_expand/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,28 @@ impl<'a> ExtCtxt<'a> {
})
}

pub fn assoc_item(
&self,
span: Span,
name: Ident,
attrs: ast::AttrVec,
kind: ast::AssocItemKind,
) -> P<ast::AssocItem> {
P(ast::Item {
ident: name,
attrs,
id: ast::DUMMY_NODE_ID,
kind,
vis: ast::Visibility {
span: span.shrink_to_lo(),
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
span,
tokens: None,
})
}

pub fn item_static(
&self,
span: Span,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ language_item_table! {
PointerLike, sym::pointer_like, pointer_like, Target::Trait, GenericRequirement::Exact(0);

CoercePointeeValidated, sym::coerce_pointee_validated, coerce_pointee_validated_trait, Target::Trait, GenericRequirement::Exact(0);
CoercePointeeValidatedPointee, sym::coerce_pointee_validated_pointee, coerce_pointee_validated_pointee, Target::AssocTy, GenericRequirement::Exact(0);

ConstParamTy, sym::const_param_ty, const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
UnsizedConstParamTy, sym::unsized_const_param_ty, unsized_const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
Expand Down
15 changes: 14 additions & 1 deletion compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,20 @@ hir_analysis_cmse_output_stack_spill =
.note1 = functions with the `"{$abi_name}"` ABI must pass their result via the available return registers
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field
hir_analysis_coerce_pointee_multiple_derive = `derive(CoercePointee)` is derived multiple times
.label = another derivation originates from here
hir_analysis_coerce_pointee_multiple_targets = `derive(CoercePointee)` only admits exactly one data field, {$diag_trait ->
[DispatchFromDyn] to which `dyn` methods shall be dispatched
*[CoerceUnsized] on which unsize coercion shall be performed
}
hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field with a `pointee` type
hir_analysis_coerce_pointee_no_generic_pointee = `CoercePointee` requires a `#[pointee]` generic type, but `{$got}` is designated as one
hir_analysis_coerce_pointee_no_pointee = `CoercePointee` requires a `#[pointee]` generic type
.label = it was set to `{$ty}` but it is among the generic parameters
hir_analysis_coerce_pointee_no_user_validity_assertion = asserting applicability of `derive(CoercePointee)` on a target data is forbidden
Expand Down
Loading

0 comments on commit e55e437

Please sign in to comment.