mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
Auto merge of #89214 - smoelius:register_tool, r=petrochenkov
Pass real crate-level attributes to `pre_expansion_lint`
The PR concerns the unstable feature `register_tool` (#66079).
The feature's implementation requires the attributes of the crate being compiled, so that when attributes like `allow(foo::bar)` are encountered, it can be verified that `register_tool(foo)` appears in the crate root.
However, the crate's attributes are not readily available during early lint passes. Specifically, on this line, `krate.attrs` appears to be the attributes of the current source file, not the attributes of the whole crate: bf642323d6/compiler/rustc_lint/src/context.rs (L815)
Consequently, "unknown tool" errors were being produced when `allow(foo::bar)` appeared in a submodule, even though `register_tool(foo)` appeared in the crate root.
EDITED: The proposed fix is to obtain the real crate-level attributes in `configure_and_expand` and pass them to `pre_expansion_lint`. (See `@petrochenkov's` [comment](https://github.com/rust-lang/rust/pull/89214#issuecomment-926927072) below.)
The original "prosed fix" text follows.
---
The proposed fix is to add an `error_on_unknown_tool` flag to `LintLevelsBuilder`. The flag controls whether "unknown tool" errors are emitted. The flag is set during late passes, but not earlier.
More specifically, this PR contains two commits:
* The first adds a `known-tool-in-submodule` UI test that does not currently pass.
* The second adds the `error_on_unknown_tool` flag. The new test passes with the addition of this flag.
This change has the added benefit of eliminating some errors that were duplicated in existing tests.
To the reviewer: please check that I implemented the UI test correctly.
This commit is contained in:
commit
98c8619502
@ -240,6 +240,7 @@ fn pre_expansion_lint(
|
||||
sess: &Session,
|
||||
lint_store: &LintStore,
|
||||
krate: &ast::Crate,
|
||||
crate_attrs: &[ast::Attribute],
|
||||
crate_name: &str,
|
||||
) {
|
||||
sess.prof.generic_activity_with_arg("pre_AST_expansion_lint_checks", crate_name).run(|| {
|
||||
@ -247,6 +248,7 @@ fn pre_expansion_lint(
|
||||
sess,
|
||||
lint_store,
|
||||
&krate,
|
||||
crate_attrs,
|
||||
true,
|
||||
None,
|
||||
rustc_lint::BuiltinCombinedPreExpansionLintPass::new(),
|
||||
@ -266,7 +268,7 @@ pub fn configure_and_expand(
|
||||
resolver: &mut Resolver<'_>,
|
||||
) -> Result<ast::Crate> {
|
||||
tracing::trace!("configure_and_expand");
|
||||
pre_expansion_lint(sess, lint_store, &krate, crate_name);
|
||||
pre_expansion_lint(sess, lint_store, &krate, &krate.attrs, crate_name);
|
||||
rustc_builtin_macros::register_builtin_macros(resolver);
|
||||
|
||||
krate = sess.time("crate_injection", || {
|
||||
@ -322,9 +324,10 @@ pub fn configure_and_expand(
|
||||
..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
|
||||
};
|
||||
|
||||
let crate_attrs = krate.attrs.clone();
|
||||
let extern_mod_loaded = |ident: Ident, attrs, items, span| {
|
||||
let krate = ast::Crate { attrs, items, span };
|
||||
pre_expansion_lint(sess, lint_store, &krate, &ident.name.as_str());
|
||||
pre_expansion_lint(sess, lint_store, &krate, &crate_attrs, &ident.name.as_str());
|
||||
(krate.attrs, krate.items)
|
||||
};
|
||||
let mut ecx = ExtCtxt::new(&sess, cfg, resolver, Some(&extern_mod_loaded));
|
||||
@ -468,6 +471,7 @@ pub fn lower_to_hir<'res, 'tcx>(
|
||||
sess,
|
||||
lint_store,
|
||||
&krate,
|
||||
&krate.attrs,
|
||||
false,
|
||||
Some(std::mem::take(resolver.lint_buffer())),
|
||||
rustc_lint::BuiltinCombinedEarlyLintPass::new(),
|
||||
|
@ -805,6 +805,7 @@ impl<'a> EarlyContext<'a> {
|
||||
sess: &'a Session,
|
||||
lint_store: &'a LintStore,
|
||||
krate: &'a ast::Crate,
|
||||
crate_attrs: &'a [ast::Attribute],
|
||||
buffered: LintBuffer,
|
||||
warn_about_weird_lints: bool,
|
||||
) -> EarlyContext<'a> {
|
||||
@ -812,7 +813,7 @@ impl<'a> EarlyContext<'a> {
|
||||
sess,
|
||||
krate,
|
||||
lint_store,
|
||||
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store, &krate.attrs),
|
||||
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store, crate_attrs),
|
||||
buffered,
|
||||
}
|
||||
}
|
||||
|
@ -329,12 +329,20 @@ fn early_lint_crate<T: EarlyLintPass>(
|
||||
sess: &Session,
|
||||
lint_store: &LintStore,
|
||||
krate: &ast::Crate,
|
||||
crate_attrs: &[ast::Attribute],
|
||||
pass: T,
|
||||
buffered: LintBuffer,
|
||||
warn_about_weird_lints: bool,
|
||||
) -> LintBuffer {
|
||||
let mut cx = EarlyContextAndPass {
|
||||
context: EarlyContext::new(sess, lint_store, krate, buffered, warn_about_weird_lints),
|
||||
context: EarlyContext::new(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
crate_attrs,
|
||||
buffered,
|
||||
warn_about_weird_lints,
|
||||
),
|
||||
pass,
|
||||
};
|
||||
|
||||
@ -355,6 +363,7 @@ pub fn check_ast_crate<T: EarlyLintPass>(
|
||||
sess: &Session,
|
||||
lint_store: &LintStore,
|
||||
krate: &ast::Crate,
|
||||
crate_attrs: &[ast::Attribute],
|
||||
pre_expansion: bool,
|
||||
lint_buffer: Option<LintBuffer>,
|
||||
builtin_lints: T,
|
||||
@ -365,14 +374,22 @@ pub fn check_ast_crate<T: EarlyLintPass>(
|
||||
let mut buffered = lint_buffer.unwrap_or_default();
|
||||
|
||||
if !sess.opts.debugging_opts.no_interleave_lints {
|
||||
buffered =
|
||||
early_lint_crate(sess, lint_store, krate, builtin_lints, buffered, pre_expansion);
|
||||
buffered = early_lint_crate(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
crate_attrs,
|
||||
builtin_lints,
|
||||
buffered,
|
||||
pre_expansion,
|
||||
);
|
||||
|
||||
if !passes.is_empty() {
|
||||
buffered = early_lint_crate(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
crate_attrs,
|
||||
EarlyLintPassObjects { lints: &mut passes[..] },
|
||||
buffered,
|
||||
false,
|
||||
@ -386,6 +403,7 @@ pub fn check_ast_crate<T: EarlyLintPass>(
|
||||
sess,
|
||||
lint_store,
|
||||
krate,
|
||||
crate_attrs,
|
||||
EarlyLintPassObjects { lints: slice::from_mut(pass) },
|
||||
buffered,
|
||||
pre_expansion && i == 0,
|
||||
|
10
src/test/ui/lint/known-tool-in-submodule/root.rs
Normal file
10
src/test/ui/lint/known-tool-in-submodule/root.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(register_tool)]
|
||||
#![register_tool(tool)]
|
||||
|
||||
mod submodule;
|
||||
|
||||
fn main() {
|
||||
submodule::foo();
|
||||
}
|
4
src/test/ui/lint/known-tool-in-submodule/submodule.rs
Normal file
4
src/test/ui/lint/known-tool-in-submodule/submodule.rs
Normal file
@ -0,0 +1,4 @@
|
||||
// ignore-test: not a test
|
||||
|
||||
#[allow(tool::lint)]
|
||||
pub fn foo() {}
|
Loading…
Reference in New Issue
Block a user