Introduce DeriveResolution
.
Making this a proper struct, and giving its fields names, makes things easier to understand.
This commit is contained in:
parent
11e95d43ae
commit
e2d2b1c698
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user