Skip to content

Commit dc99219

Browse files
committed
Auto merge of #84064 - hyd-dev:unknown-lints, r=petrochenkov
Do not ignore path segments in the middle in `#[allow]`/`#[warn]`/`#[deny]`/`#[forbid]` attributes Fixes #83477.
2 parents 83ca4b7 + ac044e3 commit dc99219

File tree

4 files changed

+85
-44
lines changed

4 files changed

+85
-44
lines changed

compiler/rustc_lint/src/levels.rs

+38-43
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,9 @@ impl<'s> LintLevelsBuilder<'s> {
236236
Some(lvl) => lvl,
237237
};
238238

239-
let meta = unwrap_or!(attr.meta(), continue);
240239
self.sess.mark_attr_used(attr);
241240

242-
let mut metas = unwrap_or!(meta.meta_item_list(), continue);
241+
let mut metas = unwrap_or!(attr.meta_item_list(), continue);
243242

244243
if metas.is_empty() {
245244
// FIXME (#55112): issue unused-attributes lint for `#[level()]`
@@ -255,8 +254,6 @@ impl<'s> LintLevelsBuilder<'s> {
255254
ast::MetaItemKind::Word => {} // actual lint names handled later
256255
ast::MetaItemKind::NameValue(ref name_value) => {
257256
if item.path == sym::reason {
258-
// found reason, reslice meta list to exclude it
259-
metas = &metas[0..metas.len() - 1];
260257
// FIXME (#55112): issue unused-attributes lint if we thereby
261258
// don't have any lint names (`#[level(reason = "foo")]`)
262259
if let ast::LitKind::Str(rationale, _) = name_value.kind {
@@ -275,6 +272,8 @@ impl<'s> LintLevelsBuilder<'s> {
275272
.span_label(name_value.span, "reason must be a string literal")
276273
.emit();
277274
}
275+
// found reason, reslice meta list to exclude it
276+
metas.pop().unwrap();
278277
} else {
279278
bad_attr(item.span)
280279
.span_label(item.span, "bad attribute argument")
@@ -288,10 +287,10 @@ impl<'s> LintLevelsBuilder<'s> {
288287
}
289288

290289
for li in metas {
291-
let meta_item = match li.meta_item() {
292-
Some(meta_item) if meta_item.is_word() => meta_item,
290+
let sp = li.span();
291+
let mut meta_item = match li {
292+
ast::NestedMetaItem::MetaItem(meta_item) if meta_item.is_word() => meta_item,
293293
_ => {
294-
let sp = li.span();
295294
let mut err = bad_attr(sp);
296295
let mut add_label = true;
297296
if let Some(item) = li.meta_item() {
@@ -330,15 +329,19 @@ impl<'s> LintLevelsBuilder<'s> {
330329
continue;
331330
}
332331

333-
Some(tool_ident.name)
332+
Some(meta_item.path.segments.remove(0).ident.name)
334333
} else {
335334
None
336335
};
337-
let name = meta_item.path.segments.last().expect("empty lint name").ident.name;
338-
let lint_result = store.check_lint_name(&name.as_str(), tool_name);
336+
let name = pprust::path_to_string(&meta_item.path);
337+
let lint_result = store.check_lint_name(&name, tool_name);
339338
match &lint_result {
340339
CheckLintNameResult::Ok(ids) => {
341-
let src = LintLevelSource::Node(name, li.span(), reason);
340+
let src = LintLevelSource::Node(
341+
meta_item.path.segments.last().expect("empty lint name").ident.name,
342+
sp,
343+
reason,
344+
);
342345
for &id in *ids {
343346
self.check_gated_lint(id, attr.span);
344347
self.insert_spec(&mut specs, id, (level, src));
@@ -351,7 +354,7 @@ impl<'s> LintLevelsBuilder<'s> {
351354
let complete_name = &format!("{}::{}", tool_name.unwrap(), name);
352355
let src = LintLevelSource::Node(
353356
Symbol::intern(complete_name),
354-
li.span(),
357+
sp,
355358
reason,
356359
);
357360
for id in ids {
@@ -367,7 +370,7 @@ impl<'s> LintLevelsBuilder<'s> {
367370
lint,
368371
lvl,
369372
src,
370-
Some(li.span().into()),
373+
Some(sp.into()),
371374
|lint| {
372375
let msg = format!(
373376
"lint name `{}` is deprecated \
@@ -376,7 +379,7 @@ impl<'s> LintLevelsBuilder<'s> {
376379
);
377380
lint.build(&msg)
378381
.span_suggestion(
379-
li.span(),
382+
sp,
380383
"change it to",
381384
new_lint_name.to_string(),
382385
Applicability::MachineApplicable,
@@ -387,7 +390,7 @@ impl<'s> LintLevelsBuilder<'s> {
387390

388391
let src = LintLevelSource::Node(
389392
Symbol::intern(&new_lint_name),
390-
li.span(),
393+
sp,
391394
reason,
392395
);
393396
for id in ids {
@@ -414,12 +417,12 @@ impl<'s> LintLevelsBuilder<'s> {
414417
lint,
415418
renamed_lint_level,
416419
src,
417-
Some(li.span().into()),
420+
Some(sp.into()),
418421
|lint| {
419422
let mut err = lint.build(&msg);
420423
if let Some(new_name) = &renamed {
421424
err.span_suggestion(
422-
li.span(),
425+
sp,
423426
"use the new name",
424427
new_name.to_string(),
425428
Applicability::MachineApplicable,
@@ -433,30 +436,23 @@ impl<'s> LintLevelsBuilder<'s> {
433436
let lint = builtin::UNKNOWN_LINTS;
434437
let (level, src) =
435438
self.sets.get_lint_level(lint, self.cur, Some(&specs), self.sess);
436-
struct_lint_level(
437-
self.sess,
438-
lint,
439-
level,
440-
src,
441-
Some(li.span().into()),
442-
|lint| {
443-
let name = if let Some(tool_name) = tool_name {
444-
format!("{}::{}", tool_name, name)
445-
} else {
446-
name.to_string()
447-
};
448-
let mut db = lint.build(&format!("unknown lint: `{}`", name));
449-
if let Some(suggestion) = suggestion {
450-
db.span_suggestion(
451-
li.span(),
452-
"did you mean",
453-
suggestion.to_string(),
454-
Applicability::MachineApplicable,
455-
);
456-
}
457-
db.emit();
458-
},
459-
);
439+
struct_lint_level(self.sess, lint, level, src, Some(sp.into()), |lint| {
440+
let name = if let Some(tool_name) = tool_name {
441+
format!("{}::{}", tool_name, name)
442+
} else {
443+
name.to_string()
444+
};
445+
let mut db = lint.build(&format!("unknown lint: `{}`", name));
446+
if let Some(suggestion) = suggestion {
447+
db.span_suggestion(
448+
sp,
449+
"did you mean",
450+
suggestion.to_string(),
451+
Applicability::MachineApplicable,
452+
);
453+
}
454+
db.emit();
455+
});
460456
}
461457
}
462458
// If this lint was renamed, apply the new lint instead of ignoring the attribute.
@@ -466,8 +462,7 @@ impl<'s> LintLevelsBuilder<'s> {
466462
// Ignore any errors or warnings that happen because the new name is inaccurate
467463
// NOTE: `new_name` already includes the tool name, so we don't have to add it again.
468464
if let CheckLintNameResult::Ok(ids) = store.check_lint_name(&new_name, None) {
469-
let src =
470-
LintLevelSource::Node(Symbol::intern(&new_name), li.span(), reason);
465+
let src = LintLevelSource::Node(Symbol::intern(&new_name), sp, reason);
471466
for &id in ids {
472467
self.check_gated_lint(id, attr.span);
473468
self.insert_spec(&mut specs, id, (level, src));

src/test/ui/lint/issue-83477.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// check-pass
2+
#![warn(rustc::internal)]
3+
4+
#[allow(rustc::foo::bar::default_hash_types)]
5+
//~^ WARN unknown lint: `rustc::foo::bar::default_hash_types`
6+
//~| HELP did you mean
7+
//~| SUGGESTION rustc::default_hash_types
8+
#[allow(rustc::foo::default_hash_types)]
9+
//~^ WARN unknown lint: `rustc::foo::default_hash_types`
10+
//~| HELP did you mean
11+
//~| SUGGESTION rustc::default_hash_types
12+
fn main() {
13+
let _ = std::collections::HashMap::<String, String>::new();
14+
//~^ WARN Prefer FxHashMap over HashMap, it has better performance
15+
//~| HELP use
16+
}

src/test/ui/lint/issue-83477.stderr

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
warning: unknown lint: `rustc::foo::bar::default_hash_types`
2+
--> $DIR/issue-83477.rs:4:9
3+
|
4+
LL | #[allow(rustc::foo::bar::default_hash_types)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
6+
|
7+
= note: `#[warn(unknown_lints)]` on by default
8+
9+
warning: unknown lint: `rustc::foo::default_hash_types`
10+
--> $DIR/issue-83477.rs:8:9
11+
|
12+
LL | #[allow(rustc::foo::default_hash_types)]
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
14+
15+
warning: Prefer FxHashMap over HashMap, it has better performance
16+
--> $DIR/issue-83477.rs:13:31
17+
|
18+
LL | let _ = std::collections::HashMap::<String, String>::new();
19+
| ^^^^^^^ help: use: `FxHashMap`
20+
|
21+
note: the lint level is defined here
22+
--> $DIR/issue-83477.rs:2:9
23+
|
24+
LL | #![warn(rustc::internal)]
25+
| ^^^^^^^^^^^^^^^
26+
= note: `#[warn(rustc::default_hash_types)]` implied by `#[warn(rustc::internal)]`
27+
= note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
28+
29+
warning: 3 warnings emitted
30+

src/tools/clippy/tests/ui/filter_methods.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![warn(clippy::all, clippy::pedantic)]
2-
#![allow(clippy::clippy::let_underscore_drop)]
2+
#![allow(clippy::let_underscore_drop)]
33
#![allow(clippy::missing_docs_in_private_items)]
44

55
fn main() {

0 commit comments

Comments
 (0)