Skip to content

Commit 86faabe

Browse files
authored
Rollup merge of rust-lang#83216 - jyn514:register-tool, r=petrochenkov
Allow registering tool lints with `register_tool` Previously, there was no way to add a custom tool prefix, even if the tool itself had registered a lint: ```rust #![feature(register_tool)] #![register_tool(xyz)] #![warn(xyz::my_lint)] ``` ``` $ rustc unknown-lint.rs --crate-type lib error[E0710]: an unknown tool name found in scoped lint: `xyz::my_lint` --> unknown-lint.rs:3:9 | 3 | #![warn(xyz::my_lint)] | ^^^ ``` This allows opting-in to lints from other tools using `register_tool`. cc rust-lang#66079 (comment), `@chorman0773` r? `@petrochenkov`
2 parents dbd1df1 + e3031fe commit 86faabe

File tree

9 files changed

+112
-32
lines changed

9 files changed

+112
-32
lines changed

compiler/rustc_ast/src/attr/mod.rs

-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ impl MarkedAttrs {
3333
}
3434
}
3535

36-
pub fn is_known_lint_tool(m_item: Ident) -> bool {
37-
[sym::clippy, sym::rustc, sym::rustdoc].contains(&m_item.name)
38-
}
39-
4036
impl NestedMetaItem {
4137
/// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`.
4238
pub fn meta_item(&self) -> Option<&MetaItem> {

compiler/rustc_lint/src/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ impl<'a> EarlyContext<'a> {
748748
sess,
749749
krate,
750750
lint_store,
751-
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store),
751+
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store, &krate.attrs),
752752
buffered,
753753
}
754754
}

compiler/rustc_lint/src/levels.rs

+37-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use crate::context::{CheckLintNameResult, LintStore};
22
use crate::late::unerased_lint_store;
33
use rustc_ast as ast;
4-
use rustc_ast::attr;
54
use rustc_ast::unwrap_or;
65
use rustc_ast_pretty::pprust;
76
use rustc_data_structures::fx::FxHashMap;
87
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
98
use rustc_hir as hir;
10-
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
9+
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
1110
use rustc_hir::{intravisit, HirId};
1211
use rustc_middle::hir::map::Map;
1312
use rustc_middle::lint::LevelAndSource;
@@ -32,7 +31,8 @@ use std::cmp;
3231
fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> LintLevelMap {
3332
assert_eq!(cnum, LOCAL_CRATE);
3433
let store = unerased_lint_store(tcx);
35-
let levels = LintLevelsBuilder::new(tcx.sess, false, &store);
34+
let crate_attrs = tcx.get_attrs(DefId { krate: cnum, index: CRATE_DEF_INDEX });
35+
let levels = LintLevelsBuilder::new(tcx.sess, false, &store, crate_attrs);
3636
let mut builder = LintLevelMapBuilder { levels, tcx, store };
3737
let krate = tcx.hir().krate();
3838

@@ -56,6 +56,7 @@ pub struct LintLevelsBuilder<'s> {
5656
cur: u32,
5757
warn_about_weird_lints: bool,
5858
store: &'s LintStore,
59+
crate_attrs: &'s [ast::Attribute],
5960
}
6061

6162
pub struct BuilderPush {
@@ -64,14 +65,20 @@ pub struct BuilderPush {
6465
}
6566

6667
impl<'s> LintLevelsBuilder<'s> {
67-
pub fn new(sess: &'s Session, warn_about_weird_lints: bool, store: &'s LintStore) -> Self {
68+
pub fn new(
69+
sess: &'s Session,
70+
warn_about_weird_lints: bool,
71+
store: &'s LintStore,
72+
crate_attrs: &'s [ast::Attribute],
73+
) -> Self {
6874
let mut builder = LintLevelsBuilder {
6975
sess,
7076
sets: LintLevelSets::new(),
7177
cur: 0,
7278
id_to_set: Default::default(),
7379
warn_about_weird_lints,
7480
store,
81+
crate_attrs,
7582
};
7683
builder.process_command_line(sess, store);
7784
assert_eq!(builder.sets.list.len(), 1);
@@ -304,15 +311,22 @@ impl<'s> LintLevelsBuilder<'s> {
304311
};
305312
let tool_name = if meta_item.path.segments.len() > 1 {
306313
let tool_ident = meta_item.path.segments[0].ident;
307-
if !attr::is_known_lint_tool(tool_ident) {
308-
struct_span_err!(
314+
if !is_known_lint_tool(tool_ident.name, sess, &self.crate_attrs) {
315+
let mut err = struct_span_err!(
309316
sess,
310317
tool_ident.span,
311318
E0710,
312-
"an unknown tool name found in scoped lint: `{}`",
319+
"unknown tool name `{}` found in scoped lint: `{}`",
320+
tool_ident.name,
313321
pprust::path_to_string(&meta_item.path),
314-
)
315-
.emit();
322+
);
323+
if sess.is_nightly_build() {
324+
err.help(&format!(
325+
"add `#![register_tool({})]` to the crate root",
326+
tool_ident.name
327+
));
328+
}
329+
err.emit();
316330
continue;
317331
}
318332

@@ -559,6 +573,20 @@ impl<'s> LintLevelsBuilder<'s> {
559573
}
560574
}
561575

576+
fn is_known_lint_tool(m_item: Symbol, sess: &Session, attrs: &[ast::Attribute]) -> bool {
577+
if [sym::clippy, sym::rustc, sym::rustdoc].contains(&m_item) {
578+
return true;
579+
}
580+
// Look for registered tools
581+
// NOTE: does no error handling; error handling is done by rustc_resolve.
582+
sess.filter_by_name(attrs, sym::register_tool)
583+
.filter_map(|attr| attr.meta_item_list())
584+
.flat_map(std::convert::identity)
585+
.filter_map(|nested_meta| nested_meta.ident())
586+
.map(|ident| ident.name)
587+
.any(|name| name == m_item)
588+
}
589+
562590
struct LintLevelMapBuilder<'a, 'tcx> {
563591
levels: LintLevelsBuilder<'tcx>,
564592
tcx: TyCtxt<'tcx>,
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![crate_type = "lib"]
2+
#![feature(register_tool)]
3+
#![register_tool(xyz)]
4+
#![warn(xyz::my_lint)] // this should not error
5+
#![warn(abc::my_lint)]
6+
//~^ ERROR unknown tool name `abc` found in scoped lint
7+
//~| HELP add `#![register_tool(abc)]`
8+
//~| ERROR unknown tool name `abc`
9+
//~| HELP add `#![register_tool(abc)]`
10+
//~| ERROR unknown tool name `abc`
11+
//~| HELP add `#![register_tool(abc)]`
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
2+
--> $DIR/register-tool-lint.rs:5:9
3+
|
4+
LL | #![warn(abc::my_lint)]
5+
| ^^^
6+
|
7+
= help: add `#![register_tool(abc)]` to the crate root
8+
9+
error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
10+
--> $DIR/register-tool-lint.rs:5:9
11+
|
12+
LL | #![warn(abc::my_lint)]
13+
| ^^^
14+
|
15+
= help: add `#![register_tool(abc)]` to the crate root
16+
17+
error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
18+
--> $DIR/register-tool-lint.rs:5:9
19+
|
20+
LL | #![warn(abc::my_lint)]
21+
| ^^^
22+
|
23+
= help: add `#![register_tool(abc)]` to the crate root
24+
25+
error: aborting due to 3 previous errors
26+
27+
For more information about this error, try `rustc --explain E0710`.

src/test/ui/tool_lints.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#[warn(foo::bar)]
2-
//~^ ERROR an unknown tool name found in scoped lint: `foo::bar`
3-
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
4-
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
2+
//~^ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
3+
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
4+
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
55
fn main() {}

src/test/ui/tool_lints.stderr

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
1+
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
22
--> $DIR/tool_lints.rs:1:8
33
|
44
LL | #[warn(foo::bar)]
55
| ^^^
6+
|
7+
= help: add `#![register_tool(foo)]` to the crate root
68

7-
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
9+
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
810
--> $DIR/tool_lints.rs:1:8
911
|
1012
LL | #[warn(foo::bar)]
1113
| ^^^
14+
|
15+
= help: add `#![register_tool(foo)]` to the crate root
1216

13-
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
17+
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
1418
--> $DIR/tool_lints.rs:1:8
1519
|
1620
LL | #[warn(foo::bar)]
1721
| ^^^
22+
|
23+
= help: add `#![register_tool(foo)]` to the crate root
1824

1925
error: aborting due to 3 previous errors
2026

src/test/ui/unknown-lint-tool-name.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
#![deny(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar`
2-
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
3-
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
1+
#![deny(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
2+
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
3+
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
44

5-
#[allow(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar`
6-
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
7-
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
5+
#[allow(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
6+
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
7+
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
88
fn main() {}

src/test/ui/unknown-lint-tool-name.stderr

+18-6
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,50 @@
1-
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
1+
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
22
--> $DIR/unknown-lint-tool-name.rs:1:9
33
|
44
LL | #![deny(foo::bar)]
55
| ^^^
6+
|
7+
= help: add `#![register_tool(foo)]` to the crate root
68

7-
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
9+
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
810
--> $DIR/unknown-lint-tool-name.rs:5:9
911
|
1012
LL | #[allow(foo::bar)]
1113
| ^^^
14+
|
15+
= help: add `#![register_tool(foo)]` to the crate root
1216

13-
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
17+
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
1418
--> $DIR/unknown-lint-tool-name.rs:1:9
1519
|
1620
LL | #![deny(foo::bar)]
1721
| ^^^
22+
|
23+
= help: add `#![register_tool(foo)]` to the crate root
1824

19-
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
25+
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
2026
--> $DIR/unknown-lint-tool-name.rs:5:9
2127
|
2228
LL | #[allow(foo::bar)]
2329
| ^^^
30+
|
31+
= help: add `#![register_tool(foo)]` to the crate root
2432

25-
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
33+
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
2634
--> $DIR/unknown-lint-tool-name.rs:1:9
2735
|
2836
LL | #![deny(foo::bar)]
2937
| ^^^
38+
|
39+
= help: add `#![register_tool(foo)]` to the crate root
3040

31-
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
41+
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
3242
--> $DIR/unknown-lint-tool-name.rs:5:9
3343
|
3444
LL | #[allow(foo::bar)]
3545
| ^^^
46+
|
47+
= help: add `#![register_tool(foo)]` to the crate root
3648

3749
error: aborting due to 6 previous errors
3850

0 commit comments

Comments
 (0)