Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 21 additions & 23 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,35 +712,33 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
}

let diagnostic_attributes: &[(Symbol, bool)] = &[
(sym::on_unimplemented, true),
(sym::do_not_recommend, true),
(sym::on_move, true),
(sym::on_const, self.tcx.features().diagnostic_on_const()),
(sym::on_unknown, self.tcx.features().diagnostic_on_unknown()),
];

if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
Copy link
Copy Markdown
Member Author

@fmease fmease Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

(preexisting) Kinda odd that we perform this check here instead of over in rustc_attr_parsing. Of course, this check has existed long before rustc_attr_parsing was introduced but now we should have better infrastructure in place.

Note that I'm not super familiar with the "low-level entry point" of the new attribute parsing infrastructure, so I don't know if there's a good reason why this check happens here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I still have plans to move feature gating to the new attribute parsing Infrastructure, but that is nicer to do after the lint attributes are ported again

&& let [namespace, attribute, ..] = &*path.segments
&& namespace.ident.name == sym::diagnostic
&& !diagnostic_attributes
.iter()
.any(|(attr, stable)| *stable && attribute.ident.name == *attr)
{
let span = attribute.span();
let candidates = diagnostic_attributes
.iter()
.filter_map(|(sym, stable)| stable.then_some(*sym))
.collect::<Vec<_>>();
let typo = find_best_match_for_name(&candidates, attribute.ident.name, Some(5))
let stable_diagnostic_attributes: Vec<_> =
[sym::on_unimplemented, sym::do_not_recommend, sym::on_move]
Copy link
Copy Markdown
Member Author

@fmease fmease Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

(preexisting) on_move "stable"? That's news to me. Should probably be gated as well. Or is it gated elsewhere?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember that attribute being gated, so it's gate is probably elsewhere

Copy link
Copy Markdown
Contributor

@mejrs mejrs Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fmease the gates are in attribute parsing, all three unstable diagnostic attrs have a check like

if !cx.features().diagnostic_on_unknown() {
return;
}

The checks in rustc_resolve here are just for typo suggestions. but on_move was merged in between the creation and merge of #152901, that's probably why it's accidentally there.

Copy link
Copy Markdown
Member Author

@fmease fmease Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, thanks, I see, obvious in hindsight

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give on_move the same feature check as on_const/on_unknown below? Thanks!

.into_iter()
.chain(self.tcx.features().diagnostic_on_const().then_some(sym::on_const))
.chain(self.tcx.features().diagnostic_on_unknown().then_some(sym::on_unknown))
.collect();

if !stable_diagnostic_attributes.iter().any(|&attr| attribute.ident.name == attr) {
let span = attribute.span();
let typo = find_best_match_for_name(
&stable_diagnostic_attributes,
attribute.ident.name,
Some(5),
Copy link
Copy Markdown
Contributor

@mejrs mejrs Apr 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

I just realized that on_move and on_const are really similar to each other (their edit distance is 4), so this should probably be

Suggested change
Some(5),
None,

)
.map(|typo_name| errors::UnknownDiagnosticAttributeTypoSugg { span, typo_name });

self.tcx.sess.psess.buffer_lint(
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
span,
node_id,
errors::UnknownDiagnosticAttribute { typo },
);
self.tcx.sess.psess.buffer_lint(
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
span,
node_id,
errors::UnknownDiagnosticAttribute { typo },
);
}
}

Ok((ext, res))
Expand Down
Loading