Skip to content

Commit

Permalink
Rollup merge of rust-lang#83216 - jyn514:register-tool, r=petrochenkov
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
Dylan-DPC authored Mar 17, 2021
2 parents dbd1df1 + e3031fe commit 86faabe
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 32 deletions.
4 changes: 0 additions & 4 deletions compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ impl MarkedAttrs {
}
}

pub fn is_known_lint_tool(m_item: Ident) -> bool {
[sym::clippy, sym::rustc, sym::rustdoc].contains(&m_item.name)
}

impl NestedMetaItem {
/// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`.
pub fn meta_item(&self) -> Option<&MetaItem> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ impl<'a> EarlyContext<'a> {
sess,
krate,
lint_store,
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store),
builder: LintLevelsBuilder::new(sess, warn_about_weird_lints, lint_store, &krate.attrs),
buffered,
}
}
Expand Down
46 changes: 37 additions & 9 deletions compiler/rustc_lint/src/levels.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use crate::context::{CheckLintNameResult, LintStore};
use crate::late::unerased_lint_store;
use rustc_ast as ast;
use rustc_ast::attr;
use rustc_ast::unwrap_or;
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::{intravisit, HirId};
use rustc_middle::hir::map::Map;
use rustc_middle::lint::LevelAndSource;
Expand All @@ -32,7 +31,8 @@ use std::cmp;
fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> LintLevelMap {
assert_eq!(cnum, LOCAL_CRATE);
let store = unerased_lint_store(tcx);
let levels = LintLevelsBuilder::new(tcx.sess, false, &store);
let crate_attrs = tcx.get_attrs(DefId { krate: cnum, index: CRATE_DEF_INDEX });
let levels = LintLevelsBuilder::new(tcx.sess, false, &store, crate_attrs);
let mut builder = LintLevelMapBuilder { levels, tcx, store };
let krate = tcx.hir().krate();

Expand All @@ -56,6 +56,7 @@ pub struct LintLevelsBuilder<'s> {
cur: u32,
warn_about_weird_lints: bool,
store: &'s LintStore,
crate_attrs: &'s [ast::Attribute],
}

pub struct BuilderPush {
Expand All @@ -64,14 +65,20 @@ pub struct BuilderPush {
}

impl<'s> LintLevelsBuilder<'s> {
pub fn new(sess: &'s Session, warn_about_weird_lints: bool, store: &'s LintStore) -> Self {
pub fn new(
sess: &'s Session,
warn_about_weird_lints: bool,
store: &'s LintStore,
crate_attrs: &'s [ast::Attribute],
) -> Self {
let mut builder = LintLevelsBuilder {
sess,
sets: LintLevelSets::new(),
cur: 0,
id_to_set: Default::default(),
warn_about_weird_lints,
store,
crate_attrs,
};
builder.process_command_line(sess, store);
assert_eq!(builder.sets.list.len(), 1);
Expand Down Expand Up @@ -304,15 +311,22 @@ impl<'s> LintLevelsBuilder<'s> {
};
let tool_name = if meta_item.path.segments.len() > 1 {
let tool_ident = meta_item.path.segments[0].ident;
if !attr::is_known_lint_tool(tool_ident) {
struct_span_err!(
if !is_known_lint_tool(tool_ident.name, sess, &self.crate_attrs) {
let mut err = struct_span_err!(
sess,
tool_ident.span,
E0710,
"an unknown tool name found in scoped lint: `{}`",
"unknown tool name `{}` found in scoped lint: `{}`",
tool_ident.name,
pprust::path_to_string(&meta_item.path),
)
.emit();
);
if sess.is_nightly_build() {
err.help(&format!(
"add `#![register_tool({})]` to the crate root",
tool_ident.name
));
}
err.emit();
continue;
}

Expand Down Expand Up @@ -559,6 +573,20 @@ impl<'s> LintLevelsBuilder<'s> {
}
}

fn is_known_lint_tool(m_item: Symbol, sess: &Session, attrs: &[ast::Attribute]) -> bool {
if [sym::clippy, sym::rustc, sym::rustdoc].contains(&m_item) {
return true;
}
// Look for registered tools
// NOTE: does no error handling; error handling is done by rustc_resolve.
sess.filter_by_name(attrs, sym::register_tool)
.filter_map(|attr| attr.meta_item_list())
.flat_map(std::convert::identity)
.filter_map(|nested_meta| nested_meta.ident())
.map(|ident| ident.name)
.any(|name| name == m_item)
}

struct LintLevelMapBuilder<'a, 'tcx> {
levels: LintLevelsBuilder<'tcx>,
tcx: TyCtxt<'tcx>,
Expand Down
11 changes: 11 additions & 0 deletions src/test/ui/lint/register-tool-lint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![crate_type = "lib"]
#![feature(register_tool)]
#![register_tool(xyz)]
#![warn(xyz::my_lint)] // this should not error
#![warn(abc::my_lint)]
//~^ ERROR unknown tool name `abc` found in scoped lint
//~| HELP add `#![register_tool(abc)]`
//~| ERROR unknown tool name `abc`
//~| HELP add `#![register_tool(abc)]`
//~| ERROR unknown tool name `abc`
//~| HELP add `#![register_tool(abc)]`
27 changes: 27 additions & 0 deletions src/test/ui/lint/register-tool-lint.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
--> $DIR/register-tool-lint.rs:5:9
|
LL | #![warn(abc::my_lint)]
| ^^^
|
= help: add `#![register_tool(abc)]` to the crate root

error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
--> $DIR/register-tool-lint.rs:5:9
|
LL | #![warn(abc::my_lint)]
| ^^^
|
= help: add `#![register_tool(abc)]` to the crate root

error[E0710]: unknown tool name `abc` found in scoped lint: `abc::my_lint`
--> $DIR/register-tool-lint.rs:5:9
|
LL | #![warn(abc::my_lint)]
| ^^^
|
= help: add `#![register_tool(abc)]` to the crate root

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0710`.
6 changes: 3 additions & 3 deletions src/test/ui/tool_lints.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[warn(foo::bar)]
//~^ ERROR an unknown tool name found in scoped lint: `foo::bar`
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
//~^ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
fn main() {}
12 changes: 9 additions & 3 deletions src/test/ui/tool_lints.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
--> $DIR/tool_lints.rs:1:8
|
LL | #[warn(foo::bar)]
| ^^^
|
= help: add `#![register_tool(foo)]` to the crate root

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

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

error: aborting due to 3 previous errors

Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/unknown-lint-tool-name.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#![deny(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar`
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
#![deny(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`

#[allow(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar`
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
//~| ERROR an unknown tool name found in scoped lint: `foo::bar`
#[allow(foo::bar)] //~ ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
//~| ERROR unknown tool name `foo` found in scoped lint: `foo::bar`
fn main() {}
24 changes: 18 additions & 6 deletions src/test/ui/unknown-lint-tool-name.stderr
Original file line number Diff line number Diff line change
@@ -1,38 +1,50 @@
error[E0710]: an unknown tool name found in scoped lint: `foo::bar`
error[E0710]: unknown tool name `foo` found in scoped lint: `foo::bar`
--> $DIR/unknown-lint-tool-name.rs:1:9
|
LL | #![deny(foo::bar)]
| ^^^
|
= help: add `#![register_tool(foo)]` to the crate root

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

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

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

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

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

error: aborting due to 6 previous errors

Expand Down

0 comments on commit 86faabe

Please sign in to comment.