Skip to content

Commit a08d43d

Browse files
committed
port #[register_tool] to the new attribute parsing infrastructure
1 parent 024ed3c commit a08d43d

File tree

15 files changed

+121
-51
lines changed

15 files changed

+121
-51
lines changed

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,6 @@ attr_parsing_limit_invalid =
260260
`limit` must be a non-negative integer
261261
.label = {$error_str}
262262
263-
attr_parsing_feature_single_word =
264-
rust features are always a single identifier, not paths with multiple segments
263+
attr_parsing_single_word =
264+
{$description} are always a single identifier, not paths with multiple segments
265265
.help = did you maybe mean `{$first_segment}`?

compiler/rustc_attr_parsing/src/attributes/crate_level.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::prelude::*;
2-
use crate::session_diagnostics::{FeatureExpectedSingleWord, LimitInvalid};
2+
use crate::session_diagnostics::{ExpectedSingleWord, LimitInvalid};
33

44
pub(crate) struct CrateNameParser;
55

@@ -186,7 +186,64 @@ impl<S: Stage> CombineAttributeParser<S> for FeatureParser {
186186
let path = elem.path();
187187
let Some(ident) = path.word() else {
188188
let first_segment = elem.path().segments().next().expect("at least one segment");
189-
cx.emit_err(FeatureExpectedSingleWord {
189+
cx.emit_err(ExpectedSingleWord {
190+
description: "rust features",
191+
span: path.span(),
192+
first_segment_span: first_segment.span,
193+
first_segment: first_segment.name,
194+
});
195+
continue;
196+
};
197+
198+
res.push(ident);
199+
}
200+
201+
res
202+
}
203+
}
204+
205+
pub(crate) struct RegisterToolParser;
206+
207+
impl<S: Stage> CombineAttributeParser<S> for RegisterToolParser {
208+
const PATH: &[Symbol] = &[sym::register_tool];
209+
type Item = Ident;
210+
const CONVERT: ConvertFn<Self::Item> = AttributeKind::RegisterTool;
211+
212+
// FIXME: recursion limit is allowed on all targets and ignored,
213+
// even though it should only be valid on crates of course
214+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
215+
const TEMPLATE: AttributeTemplate = template!(List: &["tool1, tool2, ..."]);
216+
217+
fn extend<'c>(
218+
cx: &'c mut AcceptContext<'_, '_, S>,
219+
args: &'c ArgParser<'_>,
220+
) -> impl IntoIterator<Item = Self::Item> + 'c {
221+
let ArgParser::List(list) = args else {
222+
cx.expected_list(cx.attr_span);
223+
return Vec::new();
224+
};
225+
226+
if list.is_empty() {
227+
cx.warn_empty_attribute(cx.attr_span);
228+
}
229+
230+
let mut res = Vec::new();
231+
232+
for elem in list.mixed() {
233+
let Some(elem) = elem.meta_item() else {
234+
cx.expected_identifier(elem.span());
235+
continue;
236+
};
237+
if let Err(arg_span) = elem.args().no_args() {
238+
cx.expected_no_args(arg_span);
239+
continue;
240+
}
241+
242+
let path = elem.path();
243+
let Some(ident) = path.word() else {
244+
let first_segment = elem.path().segments().next().expect("at least one segment");
245+
cx.emit_err(ExpectedSingleWord {
246+
description: "tools",
190247
span: path.span(),
191248
first_segment_span: first_segment.span,
192249
first_segment: first_segment.name,

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ use crate::attributes::codegen_attrs::{
2626
use crate::attributes::confusables::ConfusablesParser;
2727
use crate::attributes::crate_level::{
2828
CrateNameParser, FeatureParser, MoveSizeLimitParser, NoCoreParser, NoStdParser,
29-
PatternComplexityLimitParser, RecursionLimitParser, RustcCoherenceIsCoreParser,
30-
TypeLengthLimitParser,
29+
PatternComplexityLimitParser, RecursionLimitParser, RegisterToolParser,
30+
RustcCoherenceIsCoreParser, TypeLengthLimitParser,
3131
};
3232
use crate::attributes::debugger::DebuggerViualizerParser;
3333
use crate::attributes::deprecation::DeprecationParser;
@@ -169,6 +169,7 @@ attribute_parsers!(
169169
Combine<FeatureParser>,
170170
Combine<ForceTargetFeatureParser>,
171171
Combine<LinkParser>,
172+
Combine<RegisterToolParser>,
172173
Combine<ReprParser>,
173174
Combine<TargetFeatureParser>,
174175
Combine<UnstableFeatureBoundParser>,

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -970,8 +970,10 @@ pub(crate) struct LimitInvalid<'a> {
970970
}
971971

972972
#[derive(Diagnostic)]
973-
#[diag(attr_parsing_feature_single_word)]
974-
pub(crate) struct FeatureExpectedSingleWord {
973+
#[diag(attr_parsing_single_word)]
974+
pub(crate) struct ExpectedSingleWord {
975+
pub description: &'static str,
976+
975977
#[primary_span]
976978
pub span: Span,
977979

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,9 @@ fn print_crate_info(
709709
};
710710
let crate_name = passes::get_crate_name(sess, attrs);
711711
let lint_store = crate::unerased_lint_store(sess);
712-
let registered_tools = rustc_resolve::registered_tools_ast(sess.dcx(), attrs);
713712
let features = rustc_expand::config::features(sess, attrs, crate_name);
713+
let registered_tools =
714+
rustc_resolve::registered_tools_ast(sess.dcx(), attrs, sess, &features);
714715
let lint_levels = rustc_lint::LintLevelsBuilder::crate_root(
715716
sess,
716717
&features,

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,9 @@ pub enum AttributeKind {
653653
/// Represents [`#[recursion_limit]`](https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute)
654654
RecursionLimit { attr_span: Span, limit_span: Span, limit: Limit },
655655

656+
/// Represents `#[register_tool]`
657+
RegisterTool(ThinVec<Ident>, Span),
658+
656659
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
657660
Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span },
658661

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ impl AttributeKind {
8484
ProcMacroDerive { .. } => No,
8585
PubTransparent(..) => Yes,
8686
RecursionLimit { .. } => No,
87+
RegisterTool(..) => No,
8788
Repr { .. } => No,
8889
RustcBuiltinMacro { .. } => Yes,
8990
RustcCoherenceIsCore(..) => No,

compiler/rustc_passes/src/check_attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
284284
| AttributeKind::RustcCoherenceIsCore(..)
285285
| AttributeKind::DebuggerVisualizer(..)
286286
| AttributeKind::Feature(..)
287+
| AttributeKind::RegisterTool(..)
287288
) => { /* do nothing */ }
288289
Attribute::Unparsed(attr_item) => {
289290
style = Some(attr_item.style);

compiler/rustc_resolve/messages.ftl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,10 +415,6 @@ resolve_tool_module_imported =
415415
cannot use a tool module through an import
416416
.note = the tool module imported here
417417
418-
resolve_tool_only_accepts_identifiers =
419-
`{$tool}` only accepts identifiers
420-
.label = not an identifier
421-
422418
resolve_tool_was_already_registered =
423419
tool `{$tool}` was already registered
424420
.label = already registered here

compiler/rustc_resolve/src/errors.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,15 +1120,6 @@ pub(crate) struct ToolWasAlreadyRegistered {
11201120
pub(crate) old_ident_span: Span,
11211121
}
11221122

1123-
#[derive(Diagnostic)]
1124-
#[diag(resolve_tool_only_accepts_identifiers)]
1125-
pub(crate) struct ToolOnlyAcceptsIdentifiers {
1126-
#[primary_span]
1127-
#[label]
1128-
pub(crate) span: Span,
1129-
pub(crate) tool: Symbol,
1130-
}
1131-
11321123
#[derive(Subdiagnostic)]
11331124
pub(crate) enum DefinedHere {
11341125
#[label(resolve_similarly_named_defined_here)]

0 commit comments

Comments
 (0)