Skip to content

Commit dddb8d2

Browse files
committed
Implementation of tool lints
1 parent ed29e86 commit dddb8d2

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

src/librustc/diagnostics.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2137,4 +2137,5 @@ register_diagnostics! {
21372137
E0707, // multiple elided lifetimes used in arguments of `async fn`
21382138
E0708, // `async` non-`move` closures with arguments are not currently supported
21392139
E0709, // multiple different lifetimes used in arguments of `async fn`
2140+
E0710, // an unknown tool name found in scoped lint
21402141
}

src/librustc/lint/levels.rs

+23
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use session::Session;
2222
use syntax::ast;
2323
use syntax::attr;
2424
use syntax::codemap::MultiSpan;
25+
use syntax::feature_gate;
2526
use syntax::symbol::Symbol;
2627
use util::nodemap::FxHashMap;
2728

@@ -221,6 +222,28 @@ impl<'a> LintLevelsBuilder<'a> {
221222
continue
222223
}
223224
};
225+
if word.is_scoped() {
226+
if !self.sess.features_untracked().tool_lints {
227+
feature_gate::emit_feature_err(&sess.parse_sess,
228+
"tool_lints",
229+
word.span,
230+
feature_gate::GateIssue::Language,
231+
&format!("scoped lint `{}` is experimental",
232+
word.ident));
233+
}
234+
235+
if !attr::is_known_lint_tool(word) {
236+
span_err!(
237+
sess,
238+
word.span,
239+
E0710,
240+
"an unknown tool name found in scoped lint: `{}`.",
241+
word.ident
242+
);
243+
}
244+
245+
continue
246+
}
224247
let name = word.name();
225248
match store.check_lint_name(&name.as_str()) {
226249
CheckLintNameResult::Ok(ids) => {

src/libsyntax/attr/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,20 @@ pub fn is_known(attr: &Attribute) -> bool {
9090
}
9191

9292
const RUST_KNOWN_TOOL: &[&str] = &["clippy", "rustfmt"];
93+
const RUST_KNOWN_LINT_TOOL: &[&str] = &["clippy"];
9394

9495
pub fn is_known_tool(attr: &Attribute) -> bool {
9596
let tool_name =
9697
attr.path.segments.iter().next().expect("empty path in attribute").ident.name;
9798
RUST_KNOWN_TOOL.contains(&tool_name.as_str().as_ref())
9899
}
99100

101+
pub fn is_known_lint_tool(m_item: &MetaItem) -> bool {
102+
let tool_name =
103+
m_item.ident.segments.iter().next().expect("empty path in meta item").ident.name;
104+
RUST_KNOWN_LINT_TOOL.contains(&tool_name.as_str().as_ref())
105+
}
106+
100107
impl NestedMetaItem {
101108
/// Returns the MetaItem if self is a NestedMetaItemKind::MetaItem.
102109
pub fn meta_item(&self) -> Option<&MetaItem> {
@@ -290,6 +297,10 @@ impl MetaItem {
290297
pub fn is_meta_item_list(&self) -> bool {
291298
self.meta_item_list().is_some()
292299
}
300+
301+
pub fn is_scoped(&self) -> bool {
302+
self.ident.segments.len() > 1
303+
}
293304
}
294305

295306
impl Attribute {

src/libsyntax/feature_gate.rs

+2
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,8 @@ declare_features! (
458458

459459
// Scoped attributes
460460
(active, tool_attributes, "1.25.0", Some(44690), None),
461+
// Scoped lints
462+
(active, tool_lints, "1.28.0", Some(44690), None),
461463

462464
// allow irrefutable patterns in if-let and while-let statements (RFC 2086)
463465
(active, irrefutable_let_patterns, "1.27.0", Some(44495), None),

0 commit comments

Comments
 (0)