Skip to content

Commit ddfa5f6

Browse files
committed
Eliminate word_and_empty methods.
As part of this, streamline a bunch of related stuff: - Introduce `PathParser::word_sym`, as an alternative to `PathParser::word`. - Remove `MetaItemParser::path`, and just get the two parsers one at a time. - Rename `MetaItemParser::path_without_args` as `MetaItemParser::path`, and avoid the clone. - Inline and remove `MetaItemParser::word_without_args`, which has a single use. - Remove `MetaItemParser::word_or_empty_without_args`, which has a single use. - Remove `MetaItemParser::path_is`, which is unused. - Remove `MetaItemListParser::all_{word,path}_list`, which are unused.
1 parent dc8fe1f commit ddfa5f6

File tree

6 files changed

+69
-120
lines changed

6 files changed

+69
-120
lines changed

compiler/rustc_attr_parsing/src/attributes/allow_unstable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fn parse_unstable<'a>(
5353

5454
for param in list.mixed() {
5555
let param_span = param.span();
56-
if let Some(ident) = param.meta_item().and_then(|i| i.word_without_args()) {
56+
if let Some(ident) = param.meta_item().and_then(|i| i.path().word()) {
5757
res.push(ident.name);
5858
} else {
5959
cx.emit_err(session_diagnostics::ExpectsFeatures {

compiler/rustc_attr_parsing/src/attributes/deprecation.rs

+11-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use rustc_attr_data_structures::{AttributeKind, DeprecatedSince, Deprecation};
2-
use rustc_span::symbol::Ident;
32
use rustc_span::{Span, Symbol, sym};
43

54
use super::SingleAttributeParser;
@@ -13,16 +12,13 @@ pub(crate) struct DeprecationParser;
1312

1413
fn get(
1514
cx: &AcceptContext<'_>,
16-
ident: Ident,
15+
name: Symbol,
1716
param_span: Span,
1817
arg: &ArgParser<'_>,
1918
item: &Option<Symbol>,
2019
) -> Option<Symbol> {
2120
if item.is_some() {
22-
cx.emit_err(session_diagnostics::MultipleItem {
23-
span: param_span,
24-
item: ident.to_string(),
25-
});
21+
cx.emit_err(session_diagnostics::MultipleItem { span: param_span, item: name.to_string() });
2622
return None;
2723
}
2824
if let Some(v) = arg.name_value() {
@@ -83,16 +79,16 @@ impl SingleAttributeParser for DeprecationParser {
8379
return None;
8480
};
8581

86-
let (ident, arg) = param.word_or_empty();
82+
let ident_name = param.path().word_sym();
8783

88-
match ident.name {
89-
sym::since => {
90-
since = Some(get(cx, ident, param_span, arg, &since)?);
84+
match ident_name {
85+
Some(name @ sym::since) => {
86+
since = Some(get(cx, name, param_span, param.args(), &since)?);
9187
}
92-
sym::note => {
93-
note = Some(get(cx, ident, param_span, arg, &note)?);
88+
Some(name @ sym::note) => {
89+
note = Some(get(cx, name, param_span, param.args(), &note)?);
9490
}
95-
sym::suggestion => {
91+
Some(name @ sym::suggestion) => {
9692
if !features.deprecated_suggestion() {
9793
cx.emit_err(session_diagnostics::DeprecatedItemSuggestion {
9894
span: param_span,
@@ -101,12 +97,12 @@ impl SingleAttributeParser for DeprecationParser {
10197
});
10298
}
10399

104-
suggestion = Some(get(cx, ident, param_span, arg, &suggestion)?);
100+
suggestion = Some(get(cx, name, param_span, param.args(), &suggestion)?);
105101
}
106102
_ => {
107103
cx.emit_err(session_diagnostics::UnknownMetaItem {
108104
span: param_span,
109-
item: ident.to_string(),
105+
item: param.path().to_string(),
110106
expected: if features.deprecated_suggestion() {
111107
&["since", "note", "suggestion"]
112108
} else {

compiler/rustc_attr_parsing/src/attributes/repr.rs

+28-20
Original file line numberDiff line numberDiff line change
@@ -96,57 +96,65 @@ fn parse_repr(cx: &AcceptContext<'_>, param: &MetaItemParser<'_>) -> Option<Repr
9696

9797
// FIXME(jdonszelmann): invert the parsing here to match on the word first and then the
9898
// structure.
99-
let (ident, args) = param.word_or_empty();
100-
101-
match (ident.name, args) {
102-
(sym::align, ArgParser::NoArgs) => {
103-
cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident.span });
99+
let ident = param.path().word();
100+
let ident_span = ident.map_or(rustc_span::DUMMY_SP, |ident| ident.span);
101+
let name = ident.map(|ident| ident.name);
102+
let args = param.args();
103+
104+
match (name, args) {
105+
(Some(sym::align), ArgParser::NoArgs) => {
106+
cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident_span });
104107
None
105108
}
106-
(sym::align, ArgParser::List(l)) => parse_repr_align(cx, l, param.span(), AlignKind::Align),
109+
(Some(sym::align), ArgParser::List(l)) => {
110+
parse_repr_align(cx, l, param.span(), AlignKind::Align)
111+
}
107112

108-
(sym::packed, ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
109-
(sym::packed, ArgParser::List(l)) => {
113+
(Some(sym::packed), ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
114+
(Some(sym::packed), ArgParser::List(l)) => {
110115
parse_repr_align(cx, l, param.span(), AlignKind::Packed)
111116
}
112117

113-
(sym::align | sym::packed, ArgParser::NameValue(l)) => {
118+
(Some(sym::align | sym::packed), ArgParser::NameValue(l)) => {
114119
cx.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
115120
span: param.span(),
116121
// FIXME(jdonszelmann) can just be a string in the diag type
117-
repr_arg: &ident.to_string(),
122+
repr_arg: &ident.unwrap().to_string(),
118123
cause: IncorrectReprFormatGenericCause::from_lit_kind(
119124
param.span(),
120125
&l.value_as_lit().kind,
121-
ident.name.as_str(),
126+
ident.unwrap().as_str(),
122127
),
123128
});
124129
None
125130
}
126131

127-
(sym::Rust, ArgParser::NoArgs) => Some(ReprRust),
128-
(sym::C, ArgParser::NoArgs) => Some(ReprC),
129-
(sym::simd, ArgParser::NoArgs) => Some(ReprSimd),
130-
(sym::transparent, ArgParser::NoArgs) => Some(ReprTransparent),
131-
(i @ int_pat!(), ArgParser::NoArgs) => {
132+
(Some(sym::Rust), ArgParser::NoArgs) => Some(ReprRust),
133+
(Some(sym::C), ArgParser::NoArgs) => Some(ReprC),
134+
(Some(sym::simd), ArgParser::NoArgs) => Some(ReprSimd),
135+
(Some(sym::transparent), ArgParser::NoArgs) => Some(ReprTransparent),
136+
(Some(i @ int_pat!()), ArgParser::NoArgs) => {
132137
// int_pat!() should make sure it always parses
133138
Some(ReprInt(int_type_of_word(i).unwrap()))
134139
}
135140

136141
(
137-
sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(),
142+
Some(sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!()),
138143
ArgParser::NameValue(_),
139144
) => {
140145
cx.emit_err(session_diagnostics::InvalidReprHintNoValue {
141146
span: param.span(),
142-
name: ident.to_string(),
147+
name: ident.unwrap().to_string(),
143148
});
144149
None
145150
}
146-
(sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!(), ArgParser::List(_)) => {
151+
(
152+
Some(sym::Rust | sym::C | sym::simd | sym::transparent | int_pat!()),
153+
ArgParser::List(_),
154+
) => {
147155
cx.emit_err(session_diagnostics::InvalidReprHintNoParen {
148156
span: param.span(),
149-
name: ident.to_string(),
157+
name: ident.unwrap().to_string(),
150158
});
151159
None
152160
}

compiler/rustc_attr_parsing/src/attributes/stability.rs

+16-15
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ fn insert_value_into_option_or_error(
204204
if item.is_some() {
205205
cx.emit_err(session_diagnostics::MultipleItem {
206206
span: param.span(),
207-
item: param.path_without_args().to_string(),
207+
item: param.path().to_string(),
208208
});
209209
None
210210
} else if let Some(v) = param.args().name_value()
@@ -242,13 +242,13 @@ pub(crate) fn parse_stability(
242242
return None;
243243
};
244244

245-
match param.word_or_empty_without_args().name {
246-
sym::feature => insert_value_into_option_or_error(cx, &param, &mut feature)?,
247-
sym::since => insert_value_into_option_or_error(cx, &param, &mut since)?,
245+
match param.path().word_sym() {
246+
Some(sym::feature) => insert_value_into_option_or_error(cx, &param, &mut feature)?,
247+
Some(sym::since) => insert_value_into_option_or_error(cx, &param, &mut since)?,
248248
_ => {
249249
cx.emit_err(session_diagnostics::UnknownMetaItem {
250250
span: param_span,
251-
item: param.path_without_args().to_string(),
251+
item: param.path().to_string(),
252252
expected: &["feature", "since"],
253253
});
254254
return None;
@@ -310,11 +310,10 @@ pub(crate) fn parse_unstability(
310310
return None;
311311
};
312312

313-
let (word, args) = param.word_or_empty();
314-
match word.name {
315-
sym::feature => insert_value_into_option_or_error(cx, &param, &mut feature)?,
316-
sym::reason => insert_value_into_option_or_error(cx, &param, &mut reason)?,
317-
sym::issue => {
313+
match param.path().word_sym() {
314+
Some(sym::feature) => insert_value_into_option_or_error(cx, &param, &mut feature)?,
315+
Some(sym::reason) => insert_value_into_option_or_error(cx, &param, &mut reason)?,
316+
Some(sym::issue) => {
318317
insert_value_into_option_or_error(cx, &param, &mut issue)?;
319318

320319
// These unwraps are safe because `insert_value_into_option_or_error` ensures the meta item
@@ -328,7 +327,7 @@ pub(crate) fn parse_unstability(
328327
session_diagnostics::InvalidIssueString {
329328
span: param.span(),
330329
cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind(
331-
args.name_value().unwrap().value_span,
330+
param.args().name_value().unwrap().value_span,
332331
err.kind(),
333332
),
334333
},
@@ -338,17 +337,19 @@ pub(crate) fn parse_unstability(
338337
},
339338
};
340339
}
341-
sym::soft => {
342-
if !args.no_args() {
340+
Some(sym::soft) => {
341+
if !param.args().no_args() {
343342
cx.emit_err(session_diagnostics::SoftNoArgs { span: param.span() });
344343
}
345344
is_soft = true;
346345
}
347-
sym::implied_by => insert_value_into_option_or_error(cx, &param, &mut implied_by)?,
346+
Some(sym::implied_by) => {
347+
insert_value_into_option_or_error(cx, &param, &mut implied_by)?
348+
}
348349
_ => {
349350
cx.emit_err(session_diagnostics::UnknownMetaItem {
350351
span: param.span(),
351-
item: param.path_without_args().to_string(),
352+
item: param.path().to_string(),
352353
expected: &["feature", "reason", "issue", "soft", "implied_by"],
353354
});
354355
return None;

compiler/rustc_attr_parsing/src/context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,8 @@ impl<'sess> AttributeParser<'sess> {
260260
// }
261261
ast::AttrKind::Normal(n) => {
262262
let parser = MetaItemParser::from_attr(n, self.dcx());
263-
let (path, args) = parser.deconstruct();
263+
let path = parser.path();
264+
let args = parser.args();
264265
let parts = path.segments().map(|i| i.name).collect::<Vec<_>>();
265266

266267
if let Some(accepts) = ATTRIBUTE_MAPPING.0.get(parts.as_slice()) {

compiler/rustc_attr_parsing/src/parser.rs

+11-68
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ impl<'a> PathParser<'a> {
7878
(self.len() == 1).then(|| **self.segments().next().as_ref().unwrap())
7979
}
8080

81-
pub fn word_or_empty(&self) -> Ident {
82-
self.word().unwrap_or_else(Ident::empty)
81+
pub fn word_sym(&self) -> Option<Symbol> {
82+
self.word().map(|ident| ident.name)
8383
}
8484

8585
/// Asserts that this MetaItem is some specific word.
@@ -253,71 +253,28 @@ impl<'a> MetaItemParser<'a> {
253253
}
254254
}
255255

256-
/// Gets just the path, without the args.
257-
pub fn path_without_args(&self) -> PathParser<'a> {
258-
self.path.clone()
259-
}
260-
261-
/// Gets just the args parser, without caring about the path.
262-
pub fn args(&self) -> &ArgParser<'a> {
263-
&self.args
264-
}
265-
266-
pub fn deconstruct(&self) -> (PathParser<'a>, &ArgParser<'a>) {
267-
(self.path_without_args(), self.args())
268-
}
269-
270-
/// Asserts that this MetaItem starts with a path. Some examples:
256+
/// Gets a `PathParser` for a path. Some examples:
271257
///
272258
/// - `#[rustfmt::skip]`: `rustfmt::skip` is a path
273259
/// - `#[allow(clippy::complexity)]`: `clippy::complexity` is a path
274260
/// - `#[inline]`: `inline` is a single segment path
275-
pub fn path(&self) -> (PathParser<'a>, &ArgParser<'a>) {
276-
self.deconstruct()
277-
}
278-
279-
/// Asserts that this MetaItem starts with a word, or single segment path.
280-
/// Doesn't return the args parser.
281-
///
282-
/// For examples. see [`Self::word`]
283-
pub fn word_without_args(&self) -> Option<Ident> {
284-
Some(self.word()?.0)
261+
pub fn path(&self) -> &PathParser<'a> {
262+
&self.path
285263
}
286264

287-
/// Like [`word`](Self::word), but returns an empty symbol instead of None
288-
pub fn word_or_empty_without_args(&self) -> Ident {
289-
self.word_or_empty().0
265+
/// Gets just the args parser, without caring about the path.
266+
pub fn args(&self) -> &ArgParser<'a> {
267+
&self.args
290268
}
291269

292-
/// Asserts that this MetaItem starts with a word, or single segment path.
270+
/// Asserts that this MetaItem starts with some specific word.
293271
///
294272
/// Some examples:
295273
/// - `#[inline]`: `inline` is a word
296274
/// - `#[rustfmt::skip]`: `rustfmt::skip` is a path,
297275
/// and not a word and should instead be parsed using [`path`](Self::path)
298-
pub fn word(&self) -> Option<(Ident, &ArgParser<'a>)> {
299-
let (path, args) = self.deconstruct();
300-
Some((path.word()?, args))
301-
}
302-
303-
/// Like [`word`](Self::word), but returns an empty symbol instead of None
304-
pub fn word_or_empty(&self) -> (Ident, &ArgParser<'a>) {
305-
let (path, args) = self.deconstruct();
306-
(path.word().unwrap_or(Ident::empty()), args)
307-
}
308-
309-
/// Asserts that this MetaItem starts with some specific word.
310-
///
311-
/// See [`word`](Self::word) for examples of what a word is.
312276
pub fn word_is(&self, sym: Symbol) -> Option<&ArgParser<'a>> {
313-
self.path_without_args().word_is(sym).then(|| self.args())
314-
}
315-
316-
/// Asserts that this MetaItem starts with some specific path.
317-
///
318-
/// See [`word`](Self::path) for examples of what a word is.
319-
pub fn path_is(&self, segments: &[Symbol]) -> Option<&ArgParser<'a>> {
320-
self.path_without_args().segments_is(segments).then(|| self.args())
277+
self.path().word_is(sym).then(|| self.args())
321278
}
322279
}
323280

@@ -560,7 +517,7 @@ impl<'a> MetaItemListParser<'a> {
560517
}
561518

562519
/// Lets you pick and choose as what you want to parse each element in the list
563-
pub fn mixed<'s>(&'s self) -> impl Iterator<Item = &'s MetaItemOrLitParser<'a>> + 's {
520+
pub fn mixed(&self) -> impl Iterator<Item = &MetaItemOrLitParser<'a>> + '_ {
564521
self.sub_parsers.iter()
565522
}
566523

@@ -572,20 +529,6 @@ impl<'a> MetaItemListParser<'a> {
572529
self.len() == 0
573530
}
574531

575-
/// Asserts that every item in the list is another list starting with a word.
576-
///
577-
/// See [`MetaItemParser::word`] for examples of words.
578-
pub fn all_word_list<'s>(&'s self) -> Option<Vec<(Ident, &'s ArgParser<'a>)>> {
579-
self.mixed().map(|i| i.meta_item()?.word()).collect()
580-
}
581-
582-
/// Asserts that every item in the list is another list starting with a full path.
583-
///
584-
/// See [`MetaItemParser::path`] for examples of paths.
585-
pub fn all_path_list<'s>(&'s self) -> Option<Vec<(PathParser<'a>, &'s ArgParser<'a>)>> {
586-
self.mixed().map(|i| Some(i.meta_item()?.path())).collect()
587-
}
588-
589532
/// Returns Some if the list contains only a single element.
590533
///
591534
/// Inside the Some is the parser to parse this single element.

0 commit comments

Comments
 (0)