expand: Pass everything by reference to pre-expansion lint callback
This commit is contained in:
parent
05cd75504b
commit
67cccaff48
@ -925,6 +925,20 @@ pub trait ResolverExpand {
|
|||||||
fn registered_tools(&self) -> &FxHashSet<Ident>;
|
fn registered_tools(&self) -> &FxHashSet<Ident>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait LintStoreExpand {
|
||||||
|
fn pre_expansion_lint(
|
||||||
|
&self,
|
||||||
|
sess: &Session,
|
||||||
|
registered_tools: &FxHashSet<Ident>,
|
||||||
|
node_id: NodeId,
|
||||||
|
attrs: &[Attribute],
|
||||||
|
items: &[P<Item>],
|
||||||
|
name: &str,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
type LintStoreExpandDyn<'a> = Option<&'a (dyn LintStoreExpand + 'a)>;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct ModuleData {
|
pub struct ModuleData {
|
||||||
/// Path to the module starting from the crate name, like `my_crate::foo::bar`.
|
/// Path to the module starting from the crate name, like `my_crate::foo::bar`.
|
||||||
@ -959,10 +973,6 @@ pub struct ExpansionData {
|
|||||||
pub is_trailing_mac: bool,
|
pub is_trailing_mac: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
type OnExternModLoaded<'a> = Option<
|
|
||||||
&'a dyn Fn(NodeId, Vec<Attribute>, Vec<P<Item>>, Symbol) -> (Vec<Attribute>, Vec<P<Item>>),
|
|
||||||
>;
|
|
||||||
|
|
||||||
/// One of these is made during expansion and incrementally updated as we go;
|
/// One of these is made during expansion and incrementally updated as we go;
|
||||||
/// when a macro expansion occurs, the resulting nodes have the `backtrace()
|
/// when a macro expansion occurs, the resulting nodes have the `backtrace()
|
||||||
/// -> expn_data` of their expansion context stored into their span.
|
/// -> expn_data` of their expansion context stored into their span.
|
||||||
@ -977,10 +987,8 @@ pub struct ExtCtxt<'a> {
|
|||||||
/// (or during eager expansion, but that's a hack).
|
/// (or during eager expansion, but that's a hack).
|
||||||
pub force_mode: bool,
|
pub force_mode: bool,
|
||||||
pub expansions: FxHashMap<Span, Vec<String>>,
|
pub expansions: FxHashMap<Span, Vec<String>>,
|
||||||
/// Called directly after having parsed an external `mod foo;` in expansion.
|
/// Used for running pre-expansion lints on freshly loaded modules.
|
||||||
///
|
pub(super) lint_store: LintStoreExpandDyn<'a>,
|
||||||
/// `Ident` is the module name.
|
|
||||||
pub(super) extern_mod_loaded: OnExternModLoaded<'a>,
|
|
||||||
/// When we 'expand' an inert attribute, we leave it
|
/// When we 'expand' an inert attribute, we leave it
|
||||||
/// in the AST, but insert it here so that we know
|
/// in the AST, but insert it here so that we know
|
||||||
/// not to expand it again.
|
/// not to expand it again.
|
||||||
@ -992,14 +1000,14 @@ impl<'a> ExtCtxt<'a> {
|
|||||||
sess: &'a Session,
|
sess: &'a Session,
|
||||||
ecfg: expand::ExpansionConfig<'a>,
|
ecfg: expand::ExpansionConfig<'a>,
|
||||||
resolver: &'a mut dyn ResolverExpand,
|
resolver: &'a mut dyn ResolverExpand,
|
||||||
extern_mod_loaded: OnExternModLoaded<'a>,
|
lint_store: LintStoreExpandDyn<'a>,
|
||||||
) -> ExtCtxt<'a> {
|
) -> ExtCtxt<'a> {
|
||||||
ExtCtxt {
|
ExtCtxt {
|
||||||
sess,
|
sess,
|
||||||
ecfg,
|
ecfg,
|
||||||
reduced_recursion_limit: None,
|
reduced_recursion_limit: None,
|
||||||
resolver,
|
resolver,
|
||||||
extern_mod_loaded,
|
lint_store,
|
||||||
root_path: PathBuf::new(),
|
root_path: PathBuf::new(),
|
||||||
current_expansion: ExpansionData {
|
current_expansion: ExpansionData {
|
||||||
id: LocalExpnId::ROOT,
|
id: LocalExpnId::ROOT,
|
||||||
|
@ -1097,7 +1097,7 @@ impl InvocationCollectorNode for P<ast::Item> {
|
|||||||
ModKind::Unloaded => {
|
ModKind::Unloaded => {
|
||||||
// We have an outline `mod foo;` so we need to parse the file.
|
// We have an outline `mod foo;` so we need to parse the file.
|
||||||
let old_attrs_len = attrs.len();
|
let old_attrs_len = attrs.len();
|
||||||
let ParsedExternalMod { mut items, inner_span, file_path, dir_path, dir_ownership } =
|
let ParsedExternalMod { items, inner_span, file_path, dir_path, dir_ownership } =
|
||||||
parse_external_mod(
|
parse_external_mod(
|
||||||
&ecx.sess,
|
&ecx.sess,
|
||||||
ident,
|
ident,
|
||||||
@ -1107,12 +1107,14 @@ impl InvocationCollectorNode for P<ast::Item> {
|
|||||||
&mut attrs,
|
&mut attrs,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(extern_mod_loaded) = ecx.extern_mod_loaded {
|
if let Some(lint_store) = ecx.lint_store {
|
||||||
(attrs, items) = extern_mod_loaded(
|
lint_store.pre_expansion_lint(
|
||||||
|
ecx.sess,
|
||||||
|
ecx.resolver.registered_tools(),
|
||||||
ecx.current_expansion.lint_node_id,
|
ecx.current_expansion.lint_node_id,
|
||||||
attrs,
|
&attrs,
|
||||||
items,
|
&items,
|
||||||
ident.name,
|
ident.name.as_str(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ use rustc_data_structures::parallel;
|
|||||||
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
|
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
|
||||||
use rustc_data_structures::temp_dir::MaybeTempDir;
|
use rustc_data_structures::temp_dir::MaybeTempDir;
|
||||||
use rustc_errors::{Applicability, ErrorReported, PResult};
|
use rustc_errors::{Applicability, ErrorReported, PResult};
|
||||||
use rustc_expand::base::{ExtCtxt, ResolverExpand};
|
use rustc_expand::base::{ExtCtxt, LintStoreExpand, ResolverExpand};
|
||||||
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
|
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
|
||||||
use rustc_hir::Crate;
|
use rustc_hir::Crate;
|
||||||
use rustc_lint::{EarlyCheckNode, LintStore};
|
use rustc_lint::{EarlyCheckNode, LintStore};
|
||||||
@ -253,6 +253,23 @@ fn pre_expansion_lint<'a>(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cannot implement directly for `LintStore` due to trait coherence.
|
||||||
|
struct LintStoreExpandImpl<'a>(&'a LintStore);
|
||||||
|
|
||||||
|
impl LintStoreExpand for LintStoreExpandImpl<'_> {
|
||||||
|
fn pre_expansion_lint(
|
||||||
|
&self,
|
||||||
|
sess: &Session,
|
||||||
|
registered_tools: &RegisteredTools,
|
||||||
|
node_id: ast::NodeId,
|
||||||
|
attrs: &[ast::Attribute],
|
||||||
|
items: &[rustc_ast::ptr::P<ast::Item>],
|
||||||
|
name: &str,
|
||||||
|
) {
|
||||||
|
pre_expansion_lint(sess, self.0, registered_tools, (node_id, attrs, items), name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
|
/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins,
|
||||||
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
|
/// syntax expansion, secondary `cfg` expansion, synthesis of a test
|
||||||
/// harness if one is to be provided, injection of a dependency on the
|
/// harness if one is to be provided, injection of a dependency on the
|
||||||
@ -321,18 +338,8 @@ pub fn configure_and_expand(
|
|||||||
..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
|
..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
|
||||||
};
|
};
|
||||||
|
|
||||||
let registered_tools = resolver.registered_tools().clone();
|
let lint_store = LintStoreExpandImpl(lint_store);
|
||||||
let extern_mod_loaded = |node_id, attrs: Vec<_>, items: Vec<_>, name: Symbol| {
|
let mut ecx = ExtCtxt::new(sess, cfg, resolver, Some(&lint_store));
|
||||||
pre_expansion_lint(
|
|
||||||
sess,
|
|
||||||
lint_store,
|
|
||||||
®istered_tools,
|
|
||||||
(node_id, &*attrs, &*items),
|
|
||||||
name.as_str(),
|
|
||||||
);
|
|
||||||
(attrs, items)
|
|
||||||
};
|
|
||||||
let mut ecx = ExtCtxt::new(sess, cfg, resolver, Some(&extern_mod_loaded));
|
|
||||||
|
|
||||||
// Expand macros now!
|
// Expand macros now!
|
||||||
let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate));
|
let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user