Skip to content

Commit 08a12dc

Browse files
committed
Add feature hint for unstable diagnostic attributes
1 parent 55cd476 commit 08a12dc

4 files changed

Lines changed: 45 additions & 21 deletions

File tree

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: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -723,26 +723,44 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
723723
if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
724724
&& let [namespace, attribute, ..] = &*path.segments
725725
&& namespace.ident.name == sym::diagnostic
726-
&& !DIAGNOSTIC_ATTRIBUTES.iter().any(|(attr, stable)| {
726+
&& !DIAGNOSTIC_ATTRIBUTES.iter().any(|(attr, feature)| {
727727
attribute.ident.name == *attr
728-
&& stable.is_none_or(|f| self.tcx.features().enabled(f))
728+
&& feature.is_none_or(|f| self.tcx.features().enabled(f))
729729
})
730730
{
731+
let name = attribute.ident.name;
731732
let span = attribute.span();
732-
let candidates = DIAGNOSTIC_ATTRIBUTES
733-
.iter()
734-
.filter_map(|(sym, stable)| {
735-
stable.is_none_or(|f| self.tcx.features().enabled(f)).then_some(*sym)
733+
734+
let help = 'help: {
735+
if self.tcx.sess.is_nightly_build() {
736+
for (attr, feature) in DIAGNOSTIC_ATTRIBUTES {
737+
if let Some(feature) = *feature
738+
&& *attr == name
739+
{
740+
break 'help Some(errors::UnknownDiagnosticAttributeHelp::UseFeature {
741+
feature,
742+
});
743+
}
744+
}
745+
}
746+
747+
let candidates = DIAGNOSTIC_ATTRIBUTES
748+
.iter()
749+
.filter_map(|(attr, feature)| {
750+
feature.is_none_or(|f| self.tcx.features().enabled(f)).then_some(*attr)
751+
})
752+
.collect::<Vec<_>>();
753+
754+
find_best_match_for_name(&candidates, name, None).map(|typo_name| {
755+
errors::UnknownDiagnosticAttributeHelp::Typo { span, typo_name }
736756
})
737-
.collect::<Vec<_>>();
738-
let typo = find_best_match_for_name(&candidates, attribute.ident.name, None)
739-
.map(|typo_name| errors::UnknownDiagnosticAttributeTypoSugg { span, typo_name });
757+
};
740758

741759
self.tcx.sess.psess.buffer_lint(
742760
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
743761
span,
744762
node_id,
745-
errors::UnknownDiagnosticAttribute { typo },
763+
errors::UnknownDiagnosticAttribute { help },
746764
);
747765
}
748766

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ warning: unknown diagnostic attribute
44
LL | #[diagnostic::on_move(message = "Foo")]
55
| ^^^^^^^
66
|
7+
= help: add `#![feature(diagnostic_on_move)]` to the crate attributes to enable
78
= note: `#[warn(unknown_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
89

910
error[E0382]: use of moved value: `foo`

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)