Skip to content

Commit c92e28d

Browse files
committed
Add AcceptContext::expect_key_value
1 parent c7fe5e9 commit c92e28d

25 files changed

Lines changed: 349 additions & 372 deletions

compiler/rustc_attr_parsing/src/attributes/cfg.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ pub fn parse_cfg_entry<S: Stage>(
116116
else {
117117
return Err(cx.adcx().expected_identifier(meta.path().span()));
118118
};
119-
parse_name_value(name, meta.path().span(), a.name_value(), meta.span(), cx)?
119+
parse_name_value(name, meta.path().span(), a.as_name_value(), meta.span(), cx)?
120120
}
121121
},
122122
MetaItemOrLitParser::Lit(lit) => match lit.kind {
@@ -178,23 +178,16 @@ fn parse_cfg_entry_target<S: Stage>(
178178
let mut result = ThinVec::new();
179179
for sub_item in list.mixed() {
180180
// First, validate that this is a NameValue item
181-
let Some(sub_item) = sub_item.meta_item() else {
182-
cx.adcx().expected_name_value(sub_item.span(), None);
183-
continue;
184-
};
185-
let Some(nv) = sub_item.args().name_value() else {
186-
cx.adcx().expected_name_value(sub_item.span(), None);
181+
let Some((name, value)) = cx.expect_name_value(sub_item, sub_item.span(), None) else {
187182
continue;
188183
};
189184

190185
// Then, parse it as a name-value item
191-
let Some(name) = sub_item.path().word_sym().filter(|s| !s.is_path_segment_keyword()) else {
192-
return Err(cx.adcx().expected_identifier(sub_item.path().span()));
193-
};
186+
if name.is_path_segment_keyword() {
187+
return Err(cx.adcx().expected_identifier(name.span));
188+
}
194189
let name = Symbol::intern(&format!("target_{name}"));
195-
if let Ok(cfg) =
196-
parse_name_value(name, sub_item.path().span(), Some(nv), sub_item.span(), cx)
197-
{
190+
if let Ok(cfg) = parse_name_value(name, sub_item.span(), Some(value), sub_item.span(), cx) {
198191
result.push(cfg);
199192
}
200193
}

compiler/rustc_attr_parsing/src/attributes/cfi_encoding.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ impl<S: Stage> SingleAttributeParser<S> for CfiEncodingParser {
1111
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "encoding");
1212

1313
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
14-
let Some(name_value) = args.name_value() else {
15-
let attr_span = cx.attr_span;
16-
cx.adcx().expected_name_value(attr_span, Some(sym::cfi_encoding));
17-
return None;
18-
};
14+
let name_value = cx.expect_name_value(args, cx.attr_span, Some(sym::cfi_encoding))?;
1915

2016
let Some(value_str) = name_value.value_as_str() else {
2117
cx.adcx().expected_string_literal(name_value.value_span, None);

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 31 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,7 @@ impl<S: Stage> SingleAttributeParser<S> for ExportNameParser {
118118
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
119119

120120
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
121-
let Some(nv) = args.name_value() else {
122-
let attr_span = cx.attr_span;
123-
cx.adcx().expected_name_value(attr_span, None);
124-
return None;
125-
};
121+
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
126122
let Some(name) = nv.value_as_str() else {
127123
cx.adcx().expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
128124
return None;
@@ -146,11 +142,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcObjcClassParser {
146142
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "ClassName");
147143

148144
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
149-
let Some(nv) = args.name_value() else {
150-
let attr_span = cx.attr_span;
151-
cx.adcx().expected_name_value(attr_span, None);
152-
return None;
153-
};
145+
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
154146
let Some(classname) = nv.value_as_str() else {
155147
// `#[rustc_objc_class = ...]` is expected to be used as an implementation detail
156148
// inside a standard library macro, but `cx.expected_string_literal` exposes too much.
@@ -177,11 +169,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcObjcSelectorParser {
177169
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "methodName");
178170

179171
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
180-
let Some(nv) = args.name_value() else {
181-
let attr_span = cx.attr_span;
182-
cx.adcx().expected_name_value(attr_span, None);
183-
return None;
184-
};
172+
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
185173
let Some(methname) = nv.value_as_str() else {
186174
// `#[rustc_objc_selector = ...]` is expected to be used as an implementation detail
187175
// inside a standard library macro, but `cx.expected_string_literal` exposes too much.
@@ -471,29 +459,20 @@ fn parse_tf_attribute<S: Stage>(
471459
return features;
472460
}
473461
for item in list.mixed() {
474-
let Some(name_value) = item.meta_item() else {
475-
cx.adcx().expected_name_value(item.span(), Some(sym::enable));
462+
let Some((ident, value)) = cx.expect_name_value(item, item.span(), Some(sym::enable))
463+
else {
476464
return features;
477465
};
478466

479467
// Validate name
480-
let Some(name) = name_value.path().word_sym() else {
481-
cx.adcx().expected_name_value(name_value.path().span(), Some(sym::enable));
482-
return features;
483-
};
484-
if name != sym::enable {
485-
cx.adcx().expected_name_value(name_value.path().span(), Some(sym::enable));
468+
if ident.name != sym::enable {
469+
cx.adcx().expected_specific_argument(ident.span, &[sym::enable]);
486470
return features;
487471
}
488472

489473
// Use value
490-
let Some(name_value) = name_value.args().name_value() else {
491-
cx.adcx().expected_name_value(item.span(), Some(sym::enable));
492-
return features;
493-
};
494-
let Some(value_str) = name_value.value_as_str() else {
495-
cx.adcx()
496-
.expected_string_literal(name_value.value_span, Some(name_value.value_as_lit()));
474+
let Some(value_str) = value.value_as_str() else {
475+
cx.adcx().expected_string_literal(value.value_span, Some(value.value_as_lit()));
497476
return features;
498477
};
499478
for feature in value_str.as_str().split(",") {
@@ -592,14 +571,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
592571
let mut rtsan = None;
593572

594573
for item in list.mixed() {
595-
let Some(item) = item.meta_item() else {
596-
cx.adcx().expected_name_value(item.span(), None);
597-
continue;
598-
};
599-
600-
let path = item.path().word_sym();
601-
let Some(value) = item.args().name_value() else {
602-
cx.adcx().expected_name_value(item.span(), path);
574+
let Some((ident, value)) = cx.expect_name_value(item, item.span(), None) else {
603575
continue;
604576
};
605577

@@ -628,20 +600,20 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
628600
}
629601
};
630602

631-
match path {
632-
Some(sym::address) | Some(sym::kernel_address) => {
603+
match ident.name {
604+
sym::address | sym::kernel_address => {
633605
apply(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS)
634606
}
635-
Some(sym::cfi) => apply(SanitizerSet::CFI),
636-
Some(sym::kcfi) => apply(SanitizerSet::KCFI),
637-
Some(sym::memory) => apply(SanitizerSet::MEMORY),
638-
Some(sym::memtag) => apply(SanitizerSet::MEMTAG),
639-
Some(sym::shadow_call_stack) => apply(SanitizerSet::SHADOWCALLSTACK),
640-
Some(sym::thread) => apply(SanitizerSet::THREAD),
641-
Some(sym::hwaddress) | Some(sym::kernel_hwaddress) => {
607+
sym::cfi => apply(SanitizerSet::CFI),
608+
sym::kcfi => apply(SanitizerSet::KCFI),
609+
sym::memory => apply(SanitizerSet::MEMORY),
610+
sym::memtag => apply(SanitizerSet::MEMTAG),
611+
sym::shadow_call_stack => apply(SanitizerSet::SHADOWCALLSTACK),
612+
sym::thread => apply(SanitizerSet::THREAD),
613+
sym::hwaddress | sym::kernel_hwaddress => {
642614
apply(SanitizerSet::HWADDRESS | SanitizerSet::KERNELHWADDRESS)
643615
}
644-
Some(sym::realtime) => match value.value_as_str() {
616+
sym::realtime => match value.value_as_str() {
645617
Some(sym::nonblocking) => rtsan = Some(RtsanSetting::Nonblocking),
646618
Some(sym::blocking) => rtsan = Some(RtsanSetting::Blocking),
647619
Some(sym::caller) => rtsan = Some(RtsanSetting::Caller),
@@ -654,7 +626,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
654626
},
655627
_ => {
656628
cx.adcx().expected_specific_argument_strings(
657-
item.path().span(),
629+
ident.span,
658630
&[
659631
sym::address,
660632
sym::kernel_address,
@@ -725,57 +697,49 @@ impl<S: Stage> SingleAttributeParser<S> for PatchableFunctionEntryParser {
725697
let mut errored = false;
726698

727699
for item in meta_item_list.mixed() {
728-
let Some(meta_item) = item.meta_item() else {
729-
errored = true;
730-
cx.adcx().expected_name_value(item.span(), None);
731-
continue;
732-
};
733-
734-
let Some(name_value_lit) = meta_item.args().name_value() else {
735-
errored = true;
736-
cx.adcx().expected_name_value(item.span(), None);
700+
let Some((ident, value)) = cx.expect_name_value(item, item.span(), None) else {
737701
continue;
738702
};
739703

740-
let attrib_to_write = match meta_item.ident().map(|ident| ident.name) {
741-
Some(sym::prefix_nops) => {
704+
let attrib_to_write = match ident.name {
705+
sym::prefix_nops => {
742706
// Duplicate prefixes are not allowed
743707
if prefix.is_some() {
744708
errored = true;
745-
cx.adcx().duplicate_key(meta_item.path().span(), sym::prefix_nops);
709+
cx.adcx().duplicate_key(ident.span, sym::prefix_nops);
746710
continue;
747711
}
748712
&mut prefix
749713
}
750-
Some(sym::entry_nops) => {
714+
sym::entry_nops => {
751715
// Duplicate entries are not allowed
752716
if entry.is_some() {
753717
errored = true;
754-
cx.adcx().duplicate_key(meta_item.path().span(), sym::entry_nops);
718+
cx.adcx().duplicate_key(ident.span, sym::entry_nops);
755719
continue;
756720
}
757721
&mut entry
758722
}
759723
_ => {
760724
errored = true;
761725
cx.adcx().expected_specific_argument(
762-
meta_item.path().span(),
726+
ident.span,
763727
&[sym::prefix_nops, sym::entry_nops],
764728
);
765729
continue;
766730
}
767731
};
768732

769-
let rustc_ast::LitKind::Int(val, _) = name_value_lit.value_as_lit().kind else {
733+
let rustc_ast::LitKind::Int(val, _) = value.value_as_lit().kind else {
770734
errored = true;
771-
cx.adcx().expected_integer_literal(name_value_lit.value_span);
735+
cx.adcx().expected_integer_literal(value.value_span);
772736
continue;
773737
};
774738

775739
let Ok(val) = val.get().try_into() else {
776740
errored = true;
777741
cx.adcx().expected_integer_literal_in_range(
778-
name_value_lit.value_span,
742+
value.value_span,
779743
u8::MIN as isize,
780744
u8::MAX as isize,
781745
);

compiler/rustc_attr_parsing/src/attributes/crate_level.rs

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ impl<S: Stage> SingleAttributeParser<S> for CrateNameParser {
1616
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
1717

1818
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
19-
let ArgParser::NameValue(n) = args else {
20-
let attr_span = cx.attr_span;
21-
cx.adcx().expected_name_value(attr_span, None);
22-
return None;
23-
};
19+
let n = cx.expect_name_value(args, cx.attr_span, None)?;
2420

2521
let Some(name) = n.value_as_str() else {
2622
cx.adcx().expected_string_literal(n.value_span, Some(n.value_as_lit()));
@@ -47,11 +43,7 @@ impl<S: Stage> CombineAttributeParser<S> for CrateTypeParser {
4743
cx: &mut AcceptContext<'_, '_, S>,
4844
args: &ArgParser,
4945
) -> impl IntoIterator<Item = Self::Item> {
50-
let ArgParser::NameValue(n) = args else {
51-
let attr_span = cx.attr_span;
52-
cx.adcx().expected_name_value(attr_span, None);
53-
return None;
54-
};
46+
let n = cx.expect_name_value(args, cx.attr_span, None)?;
5547

5648
let Some(crate_type) = n.value_as_str() else {
5749
cx.adcx().expected_string_literal(n.value_span, Some(n.value_as_lit()));
@@ -95,11 +87,7 @@ impl<S: Stage> SingleAttributeParser<S> for RecursionLimitParser {
9587
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
9688

9789
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
98-
let ArgParser::NameValue(nv) = args else {
99-
let attr_span = cx.attr_span;
100-
cx.adcx().expected_name_value(attr_span, None);
101-
return None;
102-
};
90+
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
10391

10492
Some(AttributeKind::RecursionLimit {
10593
limit: cx.parse_limit_int(nv)?,
@@ -117,11 +105,7 @@ impl<S: Stage> SingleAttributeParser<S> for MoveSizeLimitParser {
117105
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
118106

119107
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
120-
let ArgParser::NameValue(nv) = args else {
121-
let attr_span = cx.attr_span;
122-
cx.adcx().expected_name_value(attr_span, None);
123-
return None;
124-
};
108+
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
125109

126110
Some(AttributeKind::MoveSizeLimit {
127111
limit: cx.parse_limit_int(nv)?,
@@ -140,11 +124,7 @@ impl<S: Stage> SingleAttributeParser<S> for TypeLengthLimitParser {
140124
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
141125

142126
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
143-
let ArgParser::NameValue(nv) = args else {
144-
let attr_span = cx.attr_span;
145-
cx.adcx().expected_name_value(attr_span, None);
146-
return None;
147-
};
127+
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
148128

149129
Some(AttributeKind::TypeLengthLimit {
150130
limit: cx.parse_limit_int(nv)?,
@@ -162,11 +142,7 @@ impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser {
162142
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
163143

164144
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
165-
let ArgParser::NameValue(nv) = args else {
166-
let attr_span = cx.attr_span;
167-
cx.adcx().expected_name_value(attr_span, None);
168-
return None;
169-
};
145+
let nv = cx.expect_name_value(args, cx.attr_span, None)?;
170146

171147
Some(AttributeKind::PatternComplexityLimit {
172148
limit: cx.parse_limit_int(nv)?,
@@ -219,14 +195,7 @@ impl<S: Stage> SingleAttributeParser<S> for WindowsSubsystemParser {
219195
const TEMPLATE: AttributeTemplate = template!(NameValueStr: ["windows", "console"], "https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute");
220196

221197
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
222-
let Some(nv) = args.name_value() else {
223-
let inner_span = cx.inner_span;
224-
cx.adcx().expected_name_value(
225-
args.span().unwrap_or(inner_span),
226-
Some(sym::windows_subsystem),
227-
);
228-
return None;
229-
};
198+
let nv = cx.expect_name_value(args, cx.inner_span, Some(sym::windows_subsystem))?;
230199

231200
let kind = match nv.value_as_str() {
232201
Some(sym::console) => WindowsSubsystemKind::Console,

compiler/rustc_attr_parsing/src/attributes/debugger.rs

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,24 @@ impl<S: Stage> CombineAttributeParser<S> for DebuggerViualizerParser {
2121
args: &ArgParser,
2222
) -> impl IntoIterator<Item = Self::Item> {
2323
let single = cx.expect_single_element_list(args, cx.attr_span)?;
24-
let Some(mi) = single.meta_item() else {
25-
cx.adcx().expected_name_value(single.span(), None);
26-
return None;
27-
};
28-
let path = mi.path().word_sym();
29-
let visualizer_type = match path {
30-
Some(sym::natvis_file) => DebuggerVisualizerType::Natvis,
31-
Some(sym::gdb_script_file) => DebuggerVisualizerType::GdbPrettyPrinter,
24+
let (ident, args) = cx.expect_name_value(single, single.span(), None)?;
25+
let visualizer_type = match ident.name {
26+
sym::natvis_file => DebuggerVisualizerType::Natvis,
27+
sym::gdb_script_file => DebuggerVisualizerType::GdbPrettyPrinter,
3228
_ => {
3329
cx.adcx().expected_specific_argument(
34-
mi.path().span(),
30+
ident.span,
3531
&[sym::natvis_file, sym::gdb_script_file],
3632
);
3733
return None;
3834
}
3935
};
4036

41-
let Some(path) = mi.args().name_value() else {
42-
cx.adcx().expected_name_value(single.span(), path);
43-
return None;
44-
};
45-
46-
let Some(path) = path.value_as_str() else {
47-
cx.adcx().expected_string_literal(path.value_span, Some(path.value_as_lit()));
37+
let Some(path) = args.value_as_str() else {
38+
cx.adcx().expected_string_literal(args.value_span, Some(args.value_as_lit()));
4839
return None;
4940
};
5041

51-
Some(DebugVisualizer { span: mi.span(), visualizer_type, path })
42+
Some(DebugVisualizer { span: ident.span.to(args.value_span), visualizer_type, path })
5243
}
5344
}

0 commit comments

Comments
 (0)