Skip to content

Commit 078379b

Browse files
Rollup merge of rust-lang#155174 - mejrs:on_move_gating, r=JonathanBrouwer
Improve emission of `UnknownDiagnosticAttribute` lint This checks features much less than the current implementation. See rust-lang#155155 for context. Minor fixes and comments are added in the second and third commit.
2 parents adb5efa + 08a12dc commit 078379b

File tree

8 files changed

+71
-34
lines changed

8 files changed

+71
-34
lines changed

compiler/rustc_attr_parsing/src/attributes/diagnostic/on_const.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ impl<S: Stage> AttributeParser<S> for OnConstParser {
1717
template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
1818
|this, cx, args| {
1919
if !cx.features().diagnostic_on_const() {
20+
// `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
2021
return;
2122
}
2223

compiler/rustc_attr_parsing/src/attributes/diagnostic/on_move.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ impl OnMoveParser {
2424
mode: Mode,
2525
) {
2626
if !cx.features().diagnostic_on_move() {
27+
// `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
2728
return;
2829
}
2930

compiler/rustc_attr_parsing/src/attributes/diagnostic/on_unknown.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ impl OnUnknownParser {
1818
mode: Mode,
1919
) {
2020
if !cx.features().diagnostic_on_unknown() {
21+
// `UnknownDiagnosticAttribute` is emitted in rustc_resolve/macros.rs
2122
return;
2223
}
2324
let span = cx.attr_span;

compiler/rustc_resolve/src/errors.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,20 +1521,24 @@ pub(crate) struct RedundantImportVisibility {
15211521
#[diag("unknown diagnostic attribute")]
15221522
pub(crate) struct UnknownDiagnosticAttribute {
15231523
#[subdiagnostic]
1524-
pub typo: Option<UnknownDiagnosticAttributeTypoSugg>,
1524+
pub help: Option<UnknownDiagnosticAttributeHelp>,
15251525
}
15261526

15271527
#[derive(Subdiagnostic)]
1528-
#[suggestion(
1529-
"an attribute with a similar name exists",
1530-
style = "verbose",
1531-
code = "{typo_name}",
1532-
applicability = "machine-applicable"
1533-
)]
1534-
pub(crate) struct UnknownDiagnosticAttributeTypoSugg {
1535-
#[primary_span]
1536-
pub span: Span,
1537-
pub typo_name: Symbol,
1528+
pub(crate) enum UnknownDiagnosticAttributeHelp {
1529+
#[suggestion(
1530+
"an attribute with a similar name exists",
1531+
style = "verbose",
1532+
code = "{typo_name}",
1533+
applicability = "machine-applicable"
1534+
)]
1535+
Typo {
1536+
#[primary_span]
1537+
span: Span,
1538+
typo_name: Symbol,
1539+
},
1540+
#[help("add `#![feature({$feature})]` to the crate attributes to enable")]
1541+
UseFeature { feature: Symbol },
15381542
}
15391543

15401544
// FIXME: Make this properly translatable.

compiler/rustc_resolve/src/macros.rs

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -714,34 +714,55 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
714714
feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
715715
}
716716

717-
let diagnostic_attributes: &[(Symbol, bool)] = &[
718-
(sym::on_unimplemented, true),
719-
(sym::do_not_recommend, true),
720-
(sym::on_move, true),
721-
(sym::on_const, self.tcx.features().diagnostic_on_const()),
722-
(sym::on_unknown, self.tcx.features().diagnostic_on_unknown()),
717+
const DIAGNOSTIC_ATTRIBUTES: &[(Symbol, Option<Symbol>)] = &[
718+
(sym::on_unimplemented, None),
719+
(sym::do_not_recommend, None),
720+
(sym::on_move, Some(sym::diagnostic_on_move)),
721+
(sym::on_const, Some(sym::diagnostic_on_const)),
722+
(sym::on_unknown, Some(sym::diagnostic_on_unknown)),
723723
];
724724

725725
if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
726726
&& let [namespace, attribute, ..] = &*path.segments
727727
&& namespace.ident.name == sym::diagnostic
728-
&& !diagnostic_attributes
729-
.iter()
730-
.any(|(attr, stable)| *stable && attribute.ident.name == *attr)
728+
&& !DIAGNOSTIC_ATTRIBUTES.iter().any(|(attr, feature)| {
729+
attribute.ident.name == *attr
730+
&& feature.is_none_or(|f| self.tcx.features().enabled(f))
731+
})
731732
{
733+
let name = attribute.ident.name;
732734
let span = attribute.span();
733-
let candidates = diagnostic_attributes
734-
.iter()
735-
.filter_map(|(sym, stable)| stable.then_some(*sym))
736-
.collect::<Vec<_>>();
737-
let typo = find_best_match_for_name(&candidates, attribute.ident.name, Some(5))
738-
.map(|typo_name| errors::UnknownDiagnosticAttributeTypoSugg { span, typo_name });
735+
736+
let help = 'help: {
737+
if self.tcx.sess.is_nightly_build() {
738+
for (attr, feature) in DIAGNOSTIC_ATTRIBUTES {
739+
if let Some(feature) = *feature
740+
&& *attr == name
741+
{
742+
break 'help Some(errors::UnknownDiagnosticAttributeHelp::UseFeature {
743+
feature,
744+
});
745+
}
746+
}
747+
}
748+
749+
let candidates = DIAGNOSTIC_ATTRIBUTES
750+
.iter()
751+
.filter_map(|(attr, feature)| {
752+
feature.is_none_or(|f| self.tcx.features().enabled(f)).then_some(*attr)
753+
})
754+
.collect::<Vec<_>>();
755+
756+
find_best_match_for_name(&candidates, name, None).map(|typo_name| {
757+
errors::UnknownDiagnosticAttributeHelp::Typo { span, typo_name }
758+
})
759+
};
739760

740761
self.tcx.sess.psess.buffer_lint(
741762
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
742763
span,
743764
node_id,
744-
errors::UnknownDiagnosticAttribute { typo },
765+
errors::UnknownDiagnosticAttribute { help },
745766
);
746767
}
747768

tests/ui/feature-gates/feature-gate-diagnostic-on-move.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
//! gate, but the fact that not adding the feature gate will cause the
33
//! diagnostic to not emit the custom diagnostic message
44
//!
5-
#[diagnostic::on_move(
6-
message = "Foo"
7-
)]
5+
#[diagnostic::on_move(message = "Foo")]
6+
//~^ WARN unknown diagnostic attribute
87
#[derive(Debug)]
98
struct Foo;
109

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
warning: unknown diagnostic attribute
2+
--> $DIR/feature-gate-diagnostic-on-move.rs:5:15
3+
|
4+
LL | #[diagnostic::on_move(message = "Foo")]
5+
| ^^^^^^^
6+
|
7+
= help: add `#![feature(diagnostic_on_move)]` to the crate attributes to enable
8+
= note: `#[warn(unknown_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
9+
110
error[E0382]: use of moved value: `foo`
2-
--> $DIR/feature-gate-diagnostic-on-move.rs:16:15
11+
--> $DIR/feature-gate-diagnostic-on-move.rs:15:15
312
|
413
LL | let foo = Foo;
514
| --- move occurs because `foo` has type `Foo`, which does not implement the `Copy` trait
@@ -9,21 +18,21 @@ LL | let bar = foo;
918
| ^^^ value used here after move
1019
|
1120
note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary
12-
--> $DIR/feature-gate-diagnostic-on-move.rs:11:17
21+
--> $DIR/feature-gate-diagnostic-on-move.rs:10:17
1322
|
1423
LL | fn takes_foo(_: Foo) {}
1524
| --------- ^^^ this parameter takes ownership of the value
1625
| |
1726
| in this function
1827
note: if `Foo` implemented `Clone`, you could clone the value
19-
--> $DIR/feature-gate-diagnostic-on-move.rs:9:1
28+
--> $DIR/feature-gate-diagnostic-on-move.rs:8:1
2029
|
2130
LL | struct Foo;
2231
| ^^^^^^^^^^ consider implementing `Clone` for this type
2332
...
2433
LL | takes_foo(foo);
2534
| --- you could clone this value
2635

27-
error: aborting due to 1 previous error
36+
error: aborting due to 1 previous error; 1 warning emitted
2837

2938
For more information about this error, try `rustc --explain E0382`.

tests/ui/feature-gates/feature-gate-diagnostic-on-unknown.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ error: unknown diagnostic attribute
1010
LL | #[diagnostic::on_unknown(message = "Tada")]
1111
| ^^^^^^^^^^
1212
|
13+
= help: add `#![feature(diagnostic_on_unknown)]` to the crate attributes to enable
1314
note: the lint level is defined here
1415
--> $DIR/feature-gate-diagnostic-on-unknown.rs:1:9
1516
|

0 commit comments

Comments
 (0)