Skip to content

Commit 98c8619

Browse files
committed
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: https://github.com/rust-lang/rust/blob/bf642323d621dcefeef1d8ab4711aae36e357615/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](#89214 (comment)) 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.
2 parents 2b6ed3b + 1e15bbe commit 98c8619

File tree

5 files changed

+43
-6
lines changed

5 files changed

+43
-6
lines changed

compiler/rustc_interface/src/passes.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,15 @@ fn pre_expansion_lint(
240240
sess: &Session,
241241
lint_store: &LintStore,
242242
krate: &ast::Crate,
243+
crate_attrs: &[ast::Attribute],
243244
crate_name: &str,
244245
) {
245246
sess.prof.generic_activity_with_arg("pre_AST_expansion_lint_checks", crate_name).run(|| {
246247
rustc_lint::check_ast_crate(
247248
sess,
248249
lint_store,
249250
&krate,
251+
crate_attrs,
250252
true,
251253
None,
252254
rustc_lint::BuiltinCombinedPreExpansionLintPass::new(),
@@ -266,7 +268,7 @@ pub fn configure_and_expand(
266268
resolver: &mut Resolver<'_>,
267269
) -> Result<ast::Crate> {
268270
tracing::trace!("configure_and_expand");
269-
pre_expansion_lint(sess, lint_store, &krate, crate_name);
271+
pre_expansion_lint(sess, lint_store, &krate, &krate.attrs, crate_name);
270272
rustc_builtin_macros::register_builtin_macros(resolver);
271273

272274
krate = sess.time("crate_injection", || {
@@ -322,9 +324,10 @@ pub fn configure_and_expand(
322324
..rustc_expand::expand::ExpansionConfig::default(crate_name.to_string())
323325
};
324326

327+
let crate_attrs = krate.attrs.clone();
325328
let extern_mod_loaded = |ident: Ident, attrs, items, span| {
326329
let krate = ast::Crate { attrs, items, span };
327-
pre_expansion_lint(sess, lint_store, &krate, &ident.name.as_str());
330+
pre_expansion_lint(sess, lint_store, &krate, &crate_attrs, &ident.name.as_str());
328331
(krate.attrs, krate.items)
329332
};
330333
let mut ecx = ExtCtxt::new(&sess, cfg, resolver, Some(&extern_mod_loaded));
@@ -468,6 +471,7 @@ pub fn lower_to_hir<'res, 'tcx>(
468471
sess,
469472
lint_store,
470473
&krate,
474+
&krate.attrs,
471475
false,
472476
Some(std::mem::take(resolver.lint_buffer())),
473477
rustc_lint::BuiltinCombinedEarlyLintPass::new(),

compiler/rustc_lint/src/context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -805,14 +805,15 @@ impl<'a> EarlyContext<'a> {
805805
sess: &'a Session,
806806
lint_store: &'a LintStore,
807807
krate: &'a ast::Crate,
808+
crate_attrs: &'a [ast::Attribute],
808809
buffered: LintBuffer,
809810
warn_about_weird_lints: bool,
810811
) -> EarlyContext<'a> {
811812
EarlyContext {
812813
sess,
813814
krate,
814815
lint_store,
815-
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store, &krate.attrs),
816+
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store, crate_attrs),
816817
buffered,
817818
}
818819
}

compiler/rustc_lint/src/early.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -329,12 +329,20 @@ fn early_lint_crate<T: EarlyLintPass>(
329329
sess: &Session,
330330
lint_store: &LintStore,
331331
krate: &ast::Crate,
332+
crate_attrs: &[ast::Attribute],
332333
pass: T,
333334
buffered: LintBuffer,
334335
warn_about_weird_lints: bool,
335336
) -> LintBuffer {
336337
let mut cx = EarlyContextAndPass {
337-
context: EarlyContext::new(sess, lint_store, krate, buffered, warn_about_weird_lints),
338+
context: EarlyContext::new(
339+
sess,
340+
lint_store,
341+
krate,
342+
crate_attrs,
343+
buffered,
344+
warn_about_weird_lints,
345+
),
338346
pass,
339347
};
340348

@@ -355,6 +363,7 @@ pub fn check_ast_crate<T: EarlyLintPass>(
355363
sess: &Session,
356364
lint_store: &LintStore,
357365
krate: &ast::Crate,
366+
crate_attrs: &[ast::Attribute],
358367
pre_expansion: bool,
359368
lint_buffer: Option<LintBuffer>,
360369
builtin_lints: T,
@@ -365,14 +374,22 @@ pub fn check_ast_crate<T: EarlyLintPass>(
365374
let mut buffered = lint_buffer.unwrap_or_default();
366375

367376
if !sess.opts.debugging_opts.no_interleave_lints {
368-
buffered =
369-
early_lint_crate(sess, lint_store, krate, builtin_lints, buffered, pre_expansion);
377+
buffered = early_lint_crate(
378+
sess,
379+
lint_store,
380+
krate,
381+
crate_attrs,
382+
builtin_lints,
383+
buffered,
384+
pre_expansion,
385+
);
370386

371387
if !passes.is_empty() {
372388
buffered = early_lint_crate(
373389
sess,
374390
lint_store,
375391
krate,
392+
crate_attrs,
376393
EarlyLintPassObjects { lints: &mut passes[..] },
377394
buffered,
378395
false,
@@ -386,6 +403,7 @@ pub fn check_ast_crate<T: EarlyLintPass>(
386403
sess,
387404
lint_store,
388405
krate,
406+
crate_attrs,
389407
EarlyLintPassObjects { lints: slice::from_mut(pass) },
390408
buffered,
391409
pre_expansion && i == 0,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// check-pass
2+
3+
#![feature(register_tool)]
4+
#![register_tool(tool)]
5+
6+
mod submodule;
7+
8+
fn main() {
9+
submodule::foo();
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// ignore-test: not a test
2+
3+
#[allow(tool::lint)]
4+
pub fn foo() {}

0 commit comments

Comments
 (0)