Skip to content

Commit 9ada89d

Browse files
authored
Rollup merge of #127903 - nnethercote:force_collect-improvements, r=petrochenkov
`force_collect` improvements Yet more cleanups relating to `cfg_attr` processing. r? ````@petrochenkov````
2 parents 98fdfcb + 4158a1c commit 9ada89d

File tree

5 files changed

+47
-43
lines changed

5 files changed

+47
-43
lines changed

compiler/rustc_builtin_macros/src/cmdline_attrs.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::errors;
44
use rustc_ast::attr::mk_attr;
55
use rustc_ast::token;
66
use rustc_ast::{self as ast, AttrItem, AttrStyle};
7+
use rustc_parse::parser::ForceCollect;
78
use rustc_parse::{new_parser_from_source_str, unwrap_or_emit_fatal};
89
use rustc_session::parse::ParseSess;
910
use rustc_span::FileName;
@@ -17,13 +18,14 @@ pub fn inject(krate: &mut ast::Crate, psess: &ParseSess, attrs: &[String]) {
1718
));
1819

1920
let start_span = parser.token.span;
20-
let AttrItem { unsafety, path, args, tokens: _ } = match parser.parse_attr_item(false) {
21-
Ok(ai) => ai,
22-
Err(err) => {
23-
err.emit();
24-
continue;
25-
}
26-
};
21+
let AttrItem { unsafety, path, args, tokens: _ } =
22+
match parser.parse_attr_item(ForceCollect::No) {
23+
Ok(ai) => ai,
24+
Err(err) => {
25+
err.emit();
26+
continue;
27+
}
28+
};
2729
let end_span = parser.token.span;
2830
if parser.token != token::Eof {
2931
psess.dcx().emit_err(errors::InvalidCrateAttr { span: start_span.to(end_span) });

compiler/rustc_parse/src/parser/attr.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ impl<'a> Parser<'a> {
124124
if this.eat(&token::Not) { ast::AttrStyle::Inner } else { ast::AttrStyle::Outer };
125125

126126
this.expect(&token::OpenDelim(Delimiter::Bracket))?;
127-
let item = this.parse_attr_item(false)?;
127+
let item = this.parse_attr_item(ForceCollect::No)?;
128128
this.expect(&token::CloseDelim(Delimiter::Bracket))?;
129129
let attr_sp = lo.to(this.prev_token.span);
130130

@@ -248,16 +248,15 @@ impl<'a> Parser<'a> {
248248
/// PATH
249249
/// PATH `=` UNSUFFIXED_LIT
250250
/// The delimiters or `=` are still put into the resulting token stream.
251-
pub fn parse_attr_item(&mut self, capture_tokens: bool) -> PResult<'a, ast::AttrItem> {
251+
pub fn parse_attr_item(&mut self, force_collect: ForceCollect) -> PResult<'a, ast::AttrItem> {
252252
maybe_whole!(self, NtMeta, |attr| attr.into_inner());
253253

254-
let do_parse = |this: &mut Self| {
254+
let do_parse = |this: &mut Self, _empty_attrs| {
255255
let is_unsafe = this.eat_keyword(kw::Unsafe);
256256
let unsafety = if is_unsafe {
257257
let unsafe_span = this.prev_token.span;
258258
this.psess.gated_spans.gate(sym::unsafe_attributes, unsafe_span);
259259
this.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
260-
261260
ast::Safety::Unsafe(unsafe_span)
262261
} else {
263262
ast::Safety::Default
@@ -268,10 +267,10 @@ impl<'a> Parser<'a> {
268267
if is_unsafe {
269268
this.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
270269
}
271-
Ok(ast::AttrItem { unsafety, path, args, tokens: None })
270+
Ok((ast::AttrItem { unsafety, path, args, tokens: None }, false))
272271
};
273-
// Attr items don't have attributes
274-
if capture_tokens { self.collect_tokens_no_attrs(do_parse) } else { do_parse(self) }
272+
// Attr items don't have attributes.
273+
self.collect_tokens_trailing_token(AttrWrapper::empty(), force_collect, do_parse)
275274
}
276275

277276
/// Parses attributes that appear after the opening of an item. These should
@@ -344,7 +343,7 @@ impl<'a> Parser<'a> {
344343
let mut expanded_attrs = Vec::with_capacity(1);
345344
while self.token.kind != token::Eof {
346345
let lo = self.token.span;
347-
let item = self.parse_attr_item(true)?;
346+
let item = self.parse_attr_item(ForceCollect::Yes)?;
348347
expanded_attrs.push((item, lo.to(self.prev_token.span)));
349348
if !self.eat(&token::Comma) {
350349
break;

compiler/rustc_parse/src/parser/mod.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -943,11 +943,10 @@ impl<'a> Parser<'a> {
943943
let initial_semicolon = self.token.span;
944944

945945
while self.eat(&TokenKind::Semi) {
946-
let _ =
947-
self.parse_stmt_without_recovery(false, ForceCollect::Yes).unwrap_or_else(|e| {
948-
e.cancel();
949-
None
950-
});
946+
let _ = self.parse_stmt_without_recovery(false, ForceCollect::No).unwrap_or_else(|e| {
947+
e.cancel();
948+
None
949+
});
951950
}
952951

953952
expect_err

compiler/rustc_parse/src/parser/nonterminal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ impl<'a> Parser<'a> {
171171
NonterminalKind::Path => {
172172
NtPath(P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?))
173173
}
174-
NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(true)?)),
174+
NonterminalKind::Meta => NtMeta(P(self.parse_attr_item(ForceCollect::Yes)?)),
175175
NonterminalKind::Vis => {
176176
NtVis(P(self
177177
.collect_tokens_no_attrs(|this| this.parse_visibility(FollowedByType::Yes))?))

compiler/rustc_parse/src/parser/stmt.rs

+26-22
Original file line numberDiff line numberDiff line change
@@ -72,20 +72,23 @@ impl<'a> Parser<'a> {
7272
lo,
7373
attrs,
7474
errors::InvalidVariableDeclarationSub::MissingLet,
75+
force_collect,
7576
)?
7677
} else if self.is_kw_followed_by_ident(kw::Auto) && self.may_recover() {
7778
self.bump(); // `auto`
7879
self.recover_stmt_local_after_let(
7980
lo,
8081
attrs,
8182
errors::InvalidVariableDeclarationSub::UseLetNotAuto,
83+
force_collect,
8284
)?
8385
} else if self.is_kw_followed_by_ident(sym::var) && self.may_recover() {
8486
self.bump(); // `var`
8587
self.recover_stmt_local_after_let(
8688
lo,
8789
attrs,
8890
errors::InvalidVariableDeclarationSub::UseLetNotVar,
91+
force_collect,
8992
)?
9093
} else if self.check_path()
9194
&& !self.token.is_qpath_start()
@@ -96,17 +99,17 @@ impl<'a> Parser<'a> {
9699
// or `auto trait` items. We aim to parse an arbitrary path `a::b` but not something
97100
// that starts like a path (1 token), but it fact not a path.
98101
// Also, we avoid stealing syntax from `parse_item_`.
99-
match force_collect {
100-
ForceCollect::Yes => {
101-
self.collect_tokens_no_attrs(|this| this.parse_stmt_path_start(lo, attrs))?
102+
let stmt = self.collect_tokens_trailing_token(
103+
AttrWrapper::empty(),
104+
force_collect,
105+
|this, _empty_attrs| Ok((this.parse_stmt_path_start(lo, attrs)?, false)),
106+
);
107+
match stmt {
108+
Ok(stmt) => stmt,
109+
Err(mut err) => {
110+
self.suggest_add_missing_let_for_stmt(&mut err);
111+
return Err(err);
102112
}
103-
ForceCollect::No => match self.parse_stmt_path_start(lo, attrs) {
104-
Ok(stmt) => stmt,
105-
Err(mut err) => {
106-
self.suggest_add_missing_let_for_stmt(&mut err);
107-
return Err(err);
108-
}
109-
},
110113
}
111114
} else if let Some(item) = self.parse_item_common(
112115
attrs.clone(),
@@ -123,12 +126,13 @@ impl<'a> Parser<'a> {
123126
self.mk_stmt(lo, StmtKind::Empty)
124127
} else if self.token != token::CloseDelim(Delimiter::Brace) {
125128
// Remainder are line-expr stmts.
126-
let e = match force_collect {
127-
ForceCollect::Yes => self.collect_tokens_no_attrs(|this| {
128-
this.parse_expr_res(Restrictions::STMT_EXPR, attrs)
129-
})?,
130-
ForceCollect::No => self.parse_expr_res(Restrictions::STMT_EXPR, attrs)?,
131-
};
129+
let e = self.collect_tokens_trailing_token(
130+
AttrWrapper::empty(),
131+
force_collect,
132+
|this, _empty_attrs| {
133+
Ok((this.parse_expr_res(Restrictions::STMT_EXPR, attrs)?, false))
134+
},
135+
)?;
132136
if matches!(e.kind, ExprKind::Assign(..)) && self.eat_keyword(kw::Else) {
133137
let bl = self.parse_block()?;
134138
// Destructuring assignment ... else.
@@ -231,13 +235,13 @@ impl<'a> Parser<'a> {
231235
lo: Span,
232236
attrs: AttrWrapper,
233237
subdiagnostic: fn(Span) -> errors::InvalidVariableDeclarationSub,
238+
force_collect: ForceCollect,
234239
) -> PResult<'a, Stmt> {
235-
let stmt =
236-
self.collect_tokens_trailing_token(attrs, ForceCollect::Yes, |this, attrs| {
237-
let local = this.parse_local(attrs)?;
238-
// FIXME - maybe capture semicolon in recovery?
239-
Ok((this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Let(local)), false))
240-
})?;
240+
let stmt = self.collect_tokens_trailing_token(attrs, force_collect, |this, attrs| {
241+
let local = this.parse_local(attrs)?;
242+
// FIXME - maybe capture semicolon in recovery?
243+
Ok((this.mk_stmt(lo.to(this.prev_token.span), StmtKind::Let(local)), false))
244+
})?;
241245
self.dcx()
242246
.emit_err(errors::InvalidVariableDeclaration { span: lo, sub: subdiagnostic(lo) });
243247
Ok(stmt)

0 commit comments

Comments
 (0)