Skip to content

Commit f063d66

Browse files
committed
port #[register_tool] to the new attribute parsing infrastructure
1 parent bceec5b commit f063d66

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
@@ -3,7 +3,7 @@ use std::num::IntErrorKind;
33
use rustc_hir::limit::Limit;
44

55
use super::prelude::*;
6-
use crate::session_diagnostics::{FeatureExpectedSingleWord, LimitInvalid};
6+
use crate::session_diagnostics::{ExpectedSingleWord, LimitInvalid};
77

88
impl<S: Stage> AcceptContext<'_, '_, S> {
99
fn parse_limit_int(&self, nv: &NameValueParser) -> Option<Limit> {
@@ -221,7 +221,64 @@ impl<S: Stage> CombineAttributeParser<S> for FeatureParser {
221221
let path = elem.path();
222222
let Some(ident) = path.word() else {
223223
let first_segment = elem.path().segments().next().expect("at least one segment");
224-
cx.emit_err(FeatureExpectedSingleWord {
224+
cx.emit_err(ExpectedSingleWord {
225+
description: "rust features",
226+
span: path.span(),
227+
first_segment_span: first_segment.span,
228+
first_segment: first_segment.name,
229+
});
230+
continue;
231+
};
232+
233+
res.push(ident);
234+
}
235+
236+
res
237+
}
238+
}
239+
240+
pub(crate) struct RegisterToolParser;
241+
242+
impl<S: Stage> CombineAttributeParser<S> for RegisterToolParser {
243+
const PATH: &[Symbol] = &[sym::register_tool];
244+
type Item = Ident;
245+
const CONVERT: ConvertFn<Self::Item> = AttributeKind::RegisterTool;
246+
247+
// FIXME: recursion limit is allowed on all targets and ignored,
248+
// even though it should only be valid on crates of course
249+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
250+
const TEMPLATE: AttributeTemplate = template!(List: &["tool1, tool2, ..."]);
251+
252+
fn extend<'c>(
253+
cx: &'c mut AcceptContext<'_, '_, S>,
254+
args: &'c ArgParser<'_>,
255+
) -> impl IntoIterator<Item = Self::Item> + 'c {
256+
let ArgParser::List(list) = args else {
257+
cx.expected_list(cx.attr_span);
258+
return Vec::new();
259+
};
260+
261+
if list.is_empty() {
262+
cx.warn_empty_attribute(cx.attr_span);
263+
}
264+
265+
let mut res = Vec::new();
266+
267+
for elem in list.mixed() {
268+
let Some(elem) = elem.meta_item() else {
269+
cx.expected_identifier(elem.span());
270+
continue;
271+
};
272+
if let Err(arg_span) = elem.args().no_args() {
273+
cx.expected_no_args(arg_span);
274+
continue;
275+
}
276+
277+
let path = elem.path();
278+
let Some(ident) = path.word() else {
279+
let first_segment = elem.path().segments().next().expect("at least one segment");
280+
cx.emit_err(ExpectedSingleWord {
281+
description: "tools",
225282
span: path.span(),
226283
first_segment_span: first_segment.span,
227284
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::deprecation::DeprecationParser;
3333
use crate::attributes::dummy::DummyParser;
@@ -167,6 +167,7 @@ attribute_parsers!(
167167
Combine<FeatureParser>,
168168
Combine<ForceTargetFeatureParser>,
169169
Combine<LinkParser>,
170+
Combine<RegisterToolParser>,
170171
Combine<ReprParser>,
171172
Combine<TargetFeatureParser>,
172173
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
@@ -710,8 +710,9 @@ fn print_crate_info(
710710
};
711711
let crate_name = passes::get_crate_name(sess, attrs);
712712
let lint_store = crate::unerased_lint_store(sess);
713-
let registered_tools = rustc_resolve::registered_tools_ast(sess.dcx(), attrs);
714713
let features = rustc_expand::config::features(sess, attrs, crate_name);
714+
let registered_tools =
715+
rustc_resolve::registered_tools_ast(sess.dcx(), attrs, sess, &features);
715716
let lint_levels = rustc_lint::LintLevelsBuilder::crate_root(
716717
sess,
717718
&features,

compiler/rustc_hir/src/attrs/data_structures.rs

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

636+
/// Represents `#[register_tool]`
637+
RegisterTool(ThinVec<Ident>, Span),
638+
636639
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
637640
Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span },
638641

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ impl AttributeKind {
8181
ProcMacroAttribute(..) => No,
8282
ProcMacroDerive { .. } => No,
8383
PubTransparent(..) => Yes,
84+
RegisterTool(..) => No,
8485
RecursionLimit { .. } => No,
8586
Repr { .. } => No,
8687
RustcBuiltinMacro { .. } => Yes,

compiler/rustc_passes/src/check_attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
279279
| AttributeKind::ObjcSelector { .. }
280280
| AttributeKind::RustcCoherenceIsCore(..)
281281
| AttributeKind::Feature(..)
282+
| AttributeKind::RegisterTool(..)
282283
) => { /* do nothing */ }
283284
Attribute::Unparsed(attr_item) => {
284285
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)