Skip to content

Commit 6f87e0b

Browse files
committed
use AcceptContext::single_element_list where possible
1 parent cdcecc8 commit 6f87e0b

16 files changed

Lines changed: 106 additions & 125 deletions

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,7 @@ impl<S: Stage> SingleAttributeParser<S> for OptimizeParser {
2323
const TEMPLATE: AttributeTemplate = template!(List: &["size", "speed", "none"]);
2424

2525
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
26-
let Some(list) = args.list() else {
27-
let attr_span = cx.attr_span;
28-
cx.adcx().expected_list(attr_span, args);
29-
return None;
30-
};
31-
32-
let Some(single) = list.single() else {
33-
cx.adcx().expected_single_argument(list.span, list.len());
34-
return None;
35-
};
26+
let single = cx.single_element_list(args, cx.attr_span)?;
3627

3728
let res = match single.meta_item().and_then(|i| i.path().word().map(|i| i.name)) {
3829
Some(sym::size) => OptimizeAttr::Size,
@@ -84,22 +75,13 @@ impl<S: Stage> SingleAttributeParser<S> for CoverageParser {
8475
const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::off, sym::on]);
8576

8677
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
87-
let Some(args) = args.list() else {
88-
let attr_span = cx.attr_span;
89-
cx.adcx().expected_specific_argument_and_list(attr_span, &[sym::on, sym::off]);
90-
return None;
91-
};
92-
93-
let Some(arg) = args.single() else {
94-
cx.adcx().expected_single_argument(args.span, args.len());
95-
return None;
96-
};
78+
let arg = cx.single_element_list(args, cx.attr_span)?;
9779

9880
let mut fail_incorrect_argument =
9981
|span| cx.adcx().expected_specific_argument(span, &[sym::on, sym::off]);
10082

10183
let Some(arg) = arg.meta_item() else {
102-
fail_incorrect_argument(args.span);
84+
fail_incorrect_argument(arg.span());
10385
return None;
10486
};
10587

compiler/rustc_attr_parsing/src/attributes/debugger.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,7 @@ impl<S: Stage> CombineAttributeParser<S> for DebuggerViualizerParser {
2020
cx: &mut AcceptContext<'_, '_, S>,
2121
args: &ArgParser,
2222
) -> impl IntoIterator<Item = Self::Item> {
23-
let Some(l) = args.list() else {
24-
let attr_span = cx.attr_span;
25-
cx.adcx().expected_list(attr_span, args);
26-
return None;
27-
};
28-
let Some(single) = l.single() else {
29-
cx.adcx().expected_single_argument(l.span, l.len());
30-
return None;
31-
};
23+
let single = cx.single_element_list(args, cx.attr_span)?;
3224
let Some(mi) = single.meta_item() else {
3325
cx.adcx().expected_name_value(single.span(), None);
3426
return None;

compiler/rustc_attr_parsing/src/attributes/instruction_set.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,7 @@ impl<S: Stage> SingleAttributeParser<S> for InstructionSetParser {
2020
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
2121
const POSSIBLE_SYMBOLS: &[Symbol] = &[sym::arm_a32, sym::arm_t32];
2222
const POSSIBLE_ARM_SYMBOLS: &[Symbol] = &[sym::a32, sym::t32];
23-
let Some(maybe_meta_item) = args.list().and_then(MetaItemListParser::single) else {
24-
let attr_span = cx.attr_span;
25-
cx.adcx().expected_specific_argument(attr_span, POSSIBLE_SYMBOLS);
26-
return None;
27-
};
23+
let maybe_meta_item = cx.single_element_list(args, cx.attr_span)?;
2824

2925
let Some(meta_item) = maybe_meta_item.meta_item() else {
3026
cx.adcx().expected_specific_argument(maybe_meta_item.span(), POSSIBLE_SYMBOLS);

compiler/rustc_attr_parsing/src/attributes/link_attrs.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -388,12 +388,7 @@ impl LinkParser {
388388
cx.adcx().duplicate_key(item.span(), sym::cfg);
389389
return true;
390390
}
391-
let Some(link_cfg) = item.args().list() else {
392-
cx.adcx().expected_list(item.span(), item.args());
393-
return true;
394-
};
395-
let Some(link_cfg) = link_cfg.single() else {
396-
cx.adcx().expected_single_argument(item.span(), link_cfg.len());
391+
let Some(link_cfg) = cx.single_element_list(item.args(), item.span()) else {
397392
return true;
398393
};
399394
if !features.link_cfg() {

compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,7 @@ impl<S: Stage> SingleAttributeParser<S> for CollapseDebugInfoParser {
175175
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]);
176176

177177
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
178-
let Some(list) = args.list() else {
179-
let attr_span = cx.attr_span;
180-
cx.adcx().expected_list(attr_span, args);
181-
return None;
182-
};
183-
let Some(single) = list.single() else {
184-
cx.adcx().expected_single_argument(list.span, list.len());
185-
return None;
186-
};
178+
let single = cx.single_element_list(args, cx.attr_span)?;
187179
let Some(mi) = single.meta_item() else {
188180
cx.adcx().expected_not_literal(single.span());
189181
return None;

compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLintOptDenyFieldAccessParser {
195195
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Field)]);
196196
const TEMPLATE: AttributeTemplate = template!(Word);
197197
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
198-
let Some(arg) = args.list().and_then(MetaItemListParser::single) else {
199-
let attr_span = cx.attr_span;
200-
cx.adcx().expected_single_argument(attr_span, 2);
201-
return None;
202-
};
198+
let arg = cx.single_element_list(args, cx.attr_span)?;
203199

204200
let MetaItemOrLitParser::Lit(MetaItemLit { kind: LitKind::Str(lint_message, _), .. }) = arg
205201
else {
@@ -375,19 +371,10 @@ impl<S: Stage> SingleAttributeParser<S> for RustcDeprecatedSafe2024Parser {
375371
const TEMPLATE: AttributeTemplate = template!(List: &[r#"audit_that = "...""#]);
376372

377373
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
378-
let Some(args) = args.list() else {
379-
let attr_span = cx.attr_span;
380-
cx.adcx().expected_list(attr_span, args);
381-
return None;
382-
};
383-
384-
let Some(single) = args.single() else {
385-
cx.adcx().expected_single_argument(args.span, args.len());
386-
return None;
387-
};
374+
let single = cx.single_element_list(args, cx.attr_span)?;
388375

389376
let Some(arg) = single.meta_item() else {
390-
cx.adcx().expected_name_value(args.span, None);
377+
cx.adcx().expected_name_value(single.span(), None);
391378
return None;
392379
};
393380

@@ -1082,11 +1069,7 @@ impl<S: Stage> CombineAttributeParser<S> for RustcThenThisWouldNeedParser {
10821069
if !cx.cx.sess.opts.unstable_opts.query_dep_graph {
10831070
cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" });
10841071
}
1085-
let Some(item) = args.list().and_then(|l| l.single()) else {
1086-
let inner_span = cx.inner_span;
1087-
cx.adcx().expected_single_argument(inner_span, 2);
1088-
return None;
1089-
};
1072+
let item = cx.single_element_list(args, cx.attr_span)?;
10901073
let Some(ident) = item.meta_item().and_then(|item| item.ident()) else {
10911074
cx.adcx().expected_identifier(item.span());
10921075
return None;

compiler/rustc_attr_parsing/src/attributes/test_attrs.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -208,16 +208,7 @@ impl<S: Stage> SingleAttributeParser<S> for TestRunnerParser {
208208
const TEMPLATE: AttributeTemplate = template!(List: &["path"]);
209209

210210
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
211-
let Some(list) = args.list() else {
212-
let attr_span = cx.attr_span;
213-
cx.adcx().expected_list(attr_span, args);
214-
return None;
215-
};
216-
217-
let Some(single) = list.single() else {
218-
cx.adcx().expected_single_argument(list.span, list.len());
219-
return None;
220-
};
211+
let single = cx.single_element_list(args, cx.attr_span)?;
221212

222213
let Some(meta) = single.meta_item() else {
223214
cx.adcx().expected_not_literal(single.span());

compiler/rustc_attr_parsing/src/attributes/util.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,7 @@ pub(crate) fn parse_single_integer<S: Stage>(
4141
cx: &mut AcceptContext<'_, '_, S>,
4242
args: &ArgParser,
4343
) -> Option<u128> {
44-
let Some(list) = args.list() else {
45-
let attr_span = cx.attr_span;
46-
cx.adcx().expected_list(attr_span, args);
47-
return None;
48-
};
49-
let Some(single) = list.single() else {
50-
cx.adcx().expected_single_argument(list.span, list.len());
51-
return None;
52-
};
44+
let single = cx.single_element_list(args, cx.attr_span)?;
5345
let Some(lit) = single.lit() else {
5446
cx.adcx().expected_integer_literal(single.span());
5547
return None;

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use crate::attributes::test_attrs::*;
6060
use crate::attributes::traits::*;
6161
use crate::attributes::transparency::*;
6262
use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
63-
use crate::parser::{ArgParser, RefPathParser};
63+
use crate::parser::{ArgParser, MetaItemOrLitParser, RefPathParser};
6464
use crate::session_diagnostics::{
6565
AttributeParseError, AttributeParseErrorReason, AttributeParseErrorSuggestions,
6666
ParsedDescription,
@@ -502,6 +502,36 @@ impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
502502
pub(crate) fn adcx(&mut self) -> AttributeDiagnosticContext<'_, 'f, 'sess, S> {
503503
AttributeDiagnosticContext { ctx: self, custom_suggestions: Vec::new() }
504504
}
505+
506+
/// Asserts that this MetaItem is a list that contains a single element. Emits an error and
507+
/// returns `None` if it is not the case.
508+
///
509+
/// Some examples:
510+
///
511+
/// - In `#[allow(warnings)]`, `warnings` is returned
512+
/// - In `#[cfg_attr(docsrs, doc = "foo")]`, `None` is returned, "expected a single argument
513+
/// here" is emitted.
514+
/// - In `#[cfg()]`, `None` is returned, "expected an argument here" is emitted.
515+
///
516+
/// The provided span is used as a fallback for diagnostic generation in case `arg` does not
517+
/// contain any. It should be the span of the node that contains `arg`.
518+
pub(crate) fn single_element_list<'arg>(
519+
&mut self,
520+
arg: &'arg ArgParser,
521+
span: Span,
522+
) -> Option<&'arg MetaItemOrLitParser> {
523+
let ArgParser::List(l) = arg else {
524+
self.adcx().expected_list(span, arg);
525+
return None;
526+
};
527+
528+
let Some(single) = l.single() else {
529+
self.adcx().expected_single_argument(l.span, l.len());
530+
return None;
531+
};
532+
533+
Some(single)
534+
}
505535
}
506536

507537
impl<'f, 'sess, S: Stage> Deref for AcceptContext<'f, 'sess, S> {
@@ -689,6 +719,8 @@ where
689719
)
690720
}
691721

722+
/// The provided span is used as a fallback in case `args` does not contain any. It should be
723+
/// the span of the node that contains `args`.
692724
pub(crate) fn expected_list(&mut self, span: Span, args: &ArgParser) -> ErrorGuaranteed {
693725
let span = match args {
694726
ArgParser::NoArgs => span,
@@ -745,7 +777,7 @@ where
745777
self.emit_parse_error(span, AttributeParseErrorReason::DuplicateKey(key))
746778
}
747779

748-
/// An error that should be emitted when a [`MetaItemOrLitParser`](crate::parser::MetaItemOrLitParser)
780+
/// An error that should be emitted when a [`MetaItemOrLitParser`]
749781
/// was expected *not* to be a literal, but instead a meta item.
750782
pub(crate) fn expected_not_literal(&mut self, span: Span) -> ErrorGuaranteed {
751783
self.emit_parse_error(span, AttributeParseErrorReason::ExpectedNotLiteral)

tests/ui/attributes/malformed-attrs.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ error[E0539]: malformed `coverage` attribute input
314314
--> $DIR/malformed-attrs.rs:92:1
315315
|
316316
LL | #[coverage]
317-
| ^^^^^^^^^^^ this attribute is only valid with either `on` or `off` as an argument
317+
| ^^^^^^^^^^^ expected this to be a list
318318
|
319319
help: try changing it to one of the following valid forms of the attribute
320320
|
@@ -353,7 +353,7 @@ error[E0539]: malformed `instruction_set` attribute input
353353
LL | #[instruction_set]
354354
| ^^^^^^^^^^^^^^^^^^
355355
| |
356-
| valid arguments are `arm::a32` or `arm::t32`
356+
| expected this to be a list
357357
| help: must be of the form: `#[instruction_set(set)]`
358358
|
359359
= note: for more information, visit <https://doc.rust-lang.org/reference/attributes/codegen.html#the-instruction_set-attribute>

0 commit comments

Comments
 (0)