Skip to content

Commit e55e437

Browse files
encode pointee type info and deduplicate errors
1 parent b943505 commit e55e437

File tree

22 files changed

+744
-72
lines changed

22 files changed

+744
-72
lines changed

compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs

+19-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_ast::mut_visit::MutVisitor;
44
use rustc_ast::visit::BoundKind;
55
use rustc_ast::{
66
self as ast, GenericArg, GenericBound, GenericParamKind, Generics, ItemKind, MetaItem,
7-
TraitBoundModifiers, VariantData, WherePredicate,
7+
TraitBoundModifiers, TyAlias, VariantData, WherePredicate,
88
};
99
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
1010
use rustc_errors::E0802;
@@ -92,6 +92,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
9292
}
9393
}
9494
};
95+
let pointee_ty_ident = generics.params[pointee_param_idx].ident;
9596

9697
// Create the type of `self`.
9798
let path = cx.path_all(span, false, vec![name_ident], self_params.clone());
@@ -100,11 +101,26 @@ pub(crate) fn expand_deriving_coerce_pointee(
100101
// Declare helper function that adds implementation blocks.
101102
// FIXME(dingxiangfei2009): Investigate the set of attributes on target struct to be propagated to impls
102103
let attrs = thin_vec![cx.attr_word(sym::automatically_derived, span),];
103-
// # Validity assertion which will be checked later in `rustc_hir_analysis::coherence::builtins`.
104+
// # Validity assertion
105+
// This will be checked later in `rustc_hir_analysis::coherence::builtins`.
104106
{
105107
let trait_path =
106108
cx.path_all(span, true, path!(span, core::marker::CoercePointeeValidated), vec![]);
107109
let trait_ref = cx.trait_ref(trait_path);
110+
let pointee_assoc_item = cx.assoc_item(
111+
span,
112+
Ident::new(sym::Pointee, span),
113+
thin_vec![],
114+
ast::AssocItemKind::Type(Box::new(TyAlias {
115+
defaultness: ast::Defaultness::Final,
116+
generics: ast::Generics::default(),
117+
where_clauses: ast::TyAliasWhereClauses::default(),
118+
bounds: vec![],
119+
ty: Some(
120+
cx.ty(span, ast::TyKind::Path(None, cx.path_ident(span, pointee_ty_ident))),
121+
),
122+
})),
123+
);
108124
push(Annotatable::Item(
109125
cx.item(
110126
span,
@@ -141,7 +157,7 @@ pub(crate) fn expand_deriving_coerce_pointee(
141157
},
142158
of_trait: Some(trait_ref),
143159
self_ty: self_type.clone(),
144-
items: ThinVec::new(),
160+
items: thin_vec![pointee_assoc_item],
145161
})),
146162
),
147163
));
@@ -180,7 +196,6 @@ pub(crate) fn expand_deriving_coerce_pointee(
180196
//
181197
// Find the `#[pointee]` parameter and add an `Unsize<__S>` bound to it.
182198
let mut impl_generics = generics.clone();
183-
let pointee_ty_ident = generics.params[pointee_param_idx].ident;
184199
let mut self_bounds;
185200
{
186201
let pointee = &mut impl_generics.params[pointee_param_idx];

compiler/rustc_expand/src/build.rs

+22
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,28 @@ impl<'a> ExtCtxt<'a> {
682682
})
683683
}
684684

685+
pub fn assoc_item(
686+
&self,
687+
span: Span,
688+
name: Ident,
689+
attrs: ast::AttrVec,
690+
kind: ast::AssocItemKind,
691+
) -> P<ast::AssocItem> {
692+
P(ast::Item {
693+
ident: name,
694+
attrs,
695+
id: ast::DUMMY_NODE_ID,
696+
kind,
697+
vis: ast::Visibility {
698+
span: span.shrink_to_lo(),
699+
kind: ast::VisibilityKind::Inherited,
700+
tokens: None,
701+
},
702+
span,
703+
tokens: None,
704+
})
705+
}
706+
685707
pub fn item_static(
686708
&self,
687709
span: Span,

compiler/rustc_hir/src/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ language_item_table! {
371371
PointerLike, sym::pointer_like, pointer_like, Target::Trait, GenericRequirement::Exact(0);
372372

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

375376
ConstParamTy, sym::const_param_ty, const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
376377
UnsizedConstParamTy, sym::unsized_const_param_ty, unsized_const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);

compiler/rustc_hir_analysis/messages.ftl

+14-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,20 @@ hir_analysis_cmse_output_stack_spill =
8585
.note1 = functions with the `"{$abi_name}"` ABI must pass their result via the available return registers
8686
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
8787
88-
hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field
88+
hir_analysis_coerce_pointee_multiple_derive = `derive(CoercePointee)` is derived multiple times
89+
.label = another derivation originates from here
90+
91+
hir_analysis_coerce_pointee_multiple_targets = `derive(CoercePointee)` only admits exactly one data field, {$diag_trait ->
92+
[DispatchFromDyn] to which `dyn` methods shall be dispatched
93+
*[CoerceUnsized] on which unsize coercion shall be performed
94+
}
95+
96+
hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field with a `pointee` type
97+
98+
hir_analysis_coerce_pointee_no_generic_pointee = `CoercePointee` requires a `#[pointee]` generic type, but `{$got}` is designated as one
99+
100+
hir_analysis_coerce_pointee_no_pointee = `CoercePointee` requires a `#[pointee]` generic type
101+
.label = it was set to `{$ty}` but it is among the generic parameters
89102
90103
hir_analysis_coerce_pointee_no_user_validity_assertion = asserting applicability of `derive(CoercePointee)` on a target data is forbidden
91104

0 commit comments

Comments
 (0)