Introduce DeriveResolution.

Making this a proper struct, and giving its fields names, makes things
easier to understand.
This commit is contained in:
Nicholas Nethercote 2024-04-25 15:13:53 +10:00
parent 11e95d43ae
commit e2d2b1c698
5 changed files with 32 additions and 20 deletions

View File

@ -3,7 +3,9 @@
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind}; use rustc_ast::{GenericParamKind, ItemKind, MetaItemKind, NestedMetaItem, StmtKind};
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier}; use rustc_expand::base::{
Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier,
};
use rustc_feature::AttributeTemplate; use rustc_feature::AttributeTemplate;
use rustc_parse::validate_attr; use rustc_parse::validate_attr;
use rustc_session::Session; use rustc_session::Session;
@ -60,7 +62,12 @@ fn expand(
report_path_args(sess, meta); report_path_args(sess, meta);
meta.path.clone() meta.path.clone()
}) })
.map(|path| (path, dummy_annotatable(), None, self.is_const)) .map(|path| DeriveResolution {
path,
item: dummy_annotatable(),
exts: None,
is_const: self.is_const,
})
.collect() .collect()
} }
_ => vec![], _ => vec![],
@ -69,15 +76,15 @@ fn expand(
// Do not configure or clone items unless necessary. // Do not configure or clone items unless necessary.
match &mut resolutions[..] { match &mut resolutions[..] {
[] => {} [] => {}
[(_, first_item, ..), others @ ..] => { [first, others @ ..] => {
*first_item = cfg_eval( first.item = cfg_eval(
sess, sess,
features, features,
item.clone(), item.clone(),
ecx.current_expansion.lint_node_id, ecx.current_expansion.lint_node_id,
); );
for (_, item, _, _) in others { for other in others {
*item = first_item.clone(); other.item = first.item.clone();
} }
} }
} }

View File

@ -968,7 +968,12 @@ pub fn expn_data(
/// Error type that denotes indeterminacy. /// Error type that denotes indeterminacy.
pub struct Indeterminate; pub struct Indeterminate;
pub type DeriveResolutions = Vec<(ast::Path, Annotatable, Option<Lrc<SyntaxExtension>>, bool)>; pub struct DeriveResolution {
pub path: ast::Path,
pub item: Annotatable,
pub exts: Option<Lrc<SyntaxExtension>>,
pub is_const: bool,
}
pub trait ResolverExpand { pub trait ResolverExpand {
fn next_node_id(&mut self) -> NodeId; fn next_node_id(&mut self) -> NodeId;
@ -1011,11 +1016,11 @@ fn resolve_derives(
&mut self, &mut self,
expn_id: LocalExpnId, expn_id: LocalExpnId,
force: bool, force: bool,
derive_paths: &dyn Fn() -> DeriveResolutions, derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
) -> Result<(), Indeterminate>; ) -> Result<(), Indeterminate>;
/// Take resolutions for paths inside the `#[derive(...)]` attribute with the given `ExpnId` /// Take resolutions for paths inside the `#[derive(...)]` attribute with the given `ExpnId`
/// back from resolver. /// back from resolver.
fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<DeriveResolutions>; fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>>;
/// Path resolution logic for `#[cfg_accessible(path)]`. /// Path resolution logic for `#[cfg_accessible(path)]`.
fn cfg_accessible( fn cfg_accessible(
&mut self, &mut self,

View File

@ -482,7 +482,7 @@ pub fn fully_expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragm
derive_invocations.reserve(derives.len()); derive_invocations.reserve(derives.len());
derives derives
.into_iter() .into_iter()
.map(|(path, item, _exts, is_const)| { .map(|DeriveResolution { path, item, exts: _, is_const }| {
// FIXME: Consider using the derive resolutions (`_exts`) // FIXME: Consider using the derive resolutions (`_exts`)
// instead of enqueuing the derives to be resolved again later. // instead of enqueuing the derives to be resolved again later.
let expn_id = LocalExpnId::fresh_empty(); let expn_id = LocalExpnId::fresh_empty();

View File

@ -38,7 +38,7 @@
use rustc_data_structures::steal::Steal; use rustc_data_structures::steal::Steal;
use rustc_data_structures::sync::{FreezeReadGuard, Lrc}; use rustc_data_structures::sync::{FreezeReadGuard, Lrc};
use rustc_errors::{Applicability, Diag, ErrCode}; use rustc_errors::{Applicability, Diag, ErrCode};
use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind};
use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_feature::BUILTIN_ATTRIBUTES;
use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::NonMacroAttrKind; use rustc_hir::def::NonMacroAttrKind;
@ -959,7 +959,7 @@ enum BuiltinMacroState {
} }
struct DeriveData { struct DeriveData {
resolutions: DeriveResolutions, resolutions: Vec<DeriveResolution>,
helper_attrs: Vec<(usize, Ident)>, helper_attrs: Vec<(usize, Ident)>,
has_derive_copy: bool, has_derive_copy: bool,
} }

View File

@ -15,7 +15,7 @@
use rustc_data_structures::intern::Interned; use rustc_data_structures::intern::Interned;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, StashKey}; use rustc_errors::{Applicability, StashKey};
use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand}; use rustc_expand::base::{Annotatable, DeriveResolution, Indeterminate, ResolverExpand};
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
use rustc_expand::compile_declarative_macro; use rustc_expand::compile_declarative_macro;
use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion}; use rustc_expand::expand::{AstFragment, Invocation, InvocationKind, SupportsMacroExpansion};
@ -344,7 +344,7 @@ fn resolve_derives(
&mut self, &mut self,
expn_id: LocalExpnId, expn_id: LocalExpnId,
force: bool, force: bool,
derive_paths: &dyn Fn() -> DeriveResolutions, derive_paths: &dyn Fn() -> Vec<DeriveResolution>,
) -> Result<(), Indeterminate> { ) -> Result<(), Indeterminate> {
// Block expansion of the container until we resolve all derives in it. // Block expansion of the container until we resolve all derives in it.
// This is required for two reasons: // This is required for two reasons:
@ -360,11 +360,11 @@ fn resolve_derives(
has_derive_copy: false, has_derive_copy: false,
}); });
let parent_scope = self.invocation_parent_scopes[&expn_id]; let parent_scope = self.invocation_parent_scopes[&expn_id];
for (i, (path, _, opt_ext, _)) in entry.resolutions.iter_mut().enumerate() { for (i, resolution) in entry.resolutions.iter_mut().enumerate() {
if opt_ext.is_none() { if resolution.exts.is_none() {
*opt_ext = Some( resolution.exts = Some(
match self.resolve_macro_path( match self.resolve_macro_path(
path, &resolution.path,
Some(MacroKind::Derive), Some(MacroKind::Derive),
&parent_scope, &parent_scope,
true, true,
@ -372,7 +372,7 @@ fn resolve_derives(
) { ) {
Ok((Some(ext), _)) => { Ok((Some(ext), _)) => {
if !ext.helper_attrs.is_empty() { if !ext.helper_attrs.is_empty() {
let last_seg = path.segments.last().unwrap(); let last_seg = resolution.path.segments.last().unwrap();
let span = last_seg.ident.span.normalize_to_macros_2_0(); let span = last_seg.ident.span.normalize_to_macros_2_0();
entry.helper_attrs.extend( entry.helper_attrs.extend(
ext.helper_attrs ext.helper_attrs
@ -416,7 +416,7 @@ fn resolve_derives(
Ok(()) Ok(())
} }
fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<DeriveResolutions> { fn take_derive_resolutions(&mut self, expn_id: LocalExpnId) -> Option<Vec<DeriveResolution>> {
self.derive_data.remove(&expn_id).map(|data| data.resolutions) self.derive_data.remove(&expn_id).map(|data| data.resolutions)
} }