Skip to content

Commit ee5cb9e

Browse files
committed
Auto merge of #114915 - nnethercote:Nonterminal-cleanups, r=petrochenkov
`Nonterminal`-related cleanups In #114647 I am trying to remove `Nonterminal`. It has a number of preliminary cleanups that are worth merging even if #114647 doesn't merge, so let's do them in this PR. r? `@petrochenkov`
2 parents 2ceed0b + 9e22351 commit ee5cb9e

File tree

11 files changed

+120
-92
lines changed

11 files changed

+120
-92
lines changed

compiler/rustc_ast_pretty/src/pprust/state.rs

+11
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ pub fn print_crate<'a>(
150150
/// and also addresses some specific regressions described in #63896 and #73345.
151151
fn tt_prepend_space(tt: &TokenTree, prev: &TokenTree) -> bool {
152152
if let TokenTree::Token(token, _) = prev {
153+
// No space after these tokens, e.g. `x.y`, `$e`
154+
// (The carets point to `prev`.) ^ ^
153155
if matches!(token.kind, token::Dot | token::Dollar) {
154156
return false;
155157
}
@@ -158,10 +160,19 @@ fn tt_prepend_space(tt: &TokenTree, prev: &TokenTree) -> bool {
158160
}
159161
}
160162
match tt {
163+
// No space before these tokens, e.g. `foo,`, `println!`, `x.y`
164+
// (The carets point to `token`.) ^ ^ ^
165+
//
166+
// FIXME: having `Not` here works well for macro invocations like
167+
// `println!()`, but is bad when `!` means "logical not" or "the never
168+
// type", where the lack of space causes ugliness like this:
169+
// `Fn() ->!`, `x =! y`, `if! x { f(); }`.
161170
TokenTree::Token(token, _) => !matches!(token.kind, token::Comma | token::Not | token::Dot),
171+
// No space before parentheses if preceded by these tokens, e.g. `foo(...)`
162172
TokenTree::Delimited(_, Delimiter::Parenthesis, _) => {
163173
!matches!(prev, TokenTree::Token(Token { kind: token::Ident(..), .. }, _))
164174
}
175+
// No space before brackets if preceded by these tokens, e.g. `#[...]`
165176
TokenTree::Delimited(_, Delimiter::Bracket, _) => {
166177
!matches!(prev, TokenTree::Token(Token { kind: token::Pound, .. }, _))
167178
}

compiler/rustc_expand/src/mbe/macro_parser.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ use rustc_data_structures::fx::FxHashMap;
8181
use rustc_data_structures::sync::Lrc;
8282
use rustc_errors::ErrorGuaranteed;
8383
use rustc_lint_defs::pluralize;
84-
use rustc_parse::parser::{NtOrTt, Parser};
84+
use rustc_parse::parser::{ParseNtResult, Parser};
8585
use rustc_span::symbol::Ident;
8686
use rustc_span::symbol::MacroRulesNormalizedIdent;
8787
use rustc_span::Span;
@@ -692,8 +692,8 @@ impl TtParser {
692692
Ok(nt) => nt,
693693
};
694694
let m = match nt {
695-
NtOrTt::Nt(nt) => MatchedNonterminal(Lrc::new(nt)),
696-
NtOrTt::Tt(tt) => MatchedTokenTree(tt),
695+
ParseNtResult::Nt(nt) => MatchedNonterminal(Lrc::new(nt)),
696+
ParseNtResult::Tt(tt) => MatchedTokenTree(tt),
697697
};
698698
mp.push_match(next_metavar, seq_depth, m);
699699
mp.idx += 1;

compiler/rustc_expand/src/mbe/macro_rules.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1328,7 +1328,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
13281328
_ => IsInFollow::No(TOKENS),
13291329
}
13301330
}
1331-
NonterminalKind::PatWithOr { .. } => {
1331+
NonterminalKind::PatWithOr => {
13321332
const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`if`", "`in`"];
13331333
match tok {
13341334
TokenTree::Token(token) => match token.kind {

compiler/rustc_expand/src/mbe/transcribe.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,15 @@ pub(super) fn transcribe<'a>(
220220
MatchedTokenTree(tt) => {
221221
// `tt`s are emitted into the output stream directly as "raw tokens",
222222
// without wrapping them into groups.
223-
let token = tt.clone();
224-
result.push(token);
223+
result.push(tt.clone());
225224
}
226225
MatchedNonterminal(nt) => {
227226
// Other variables are emitted into the output stream as groups with
228227
// `Delimiter::Invisible` to maintain parsing priorities.
229228
// `Interpolated` is currently used for such groups in rustc parser.
230229
marker.visit_span(&mut sp);
231-
let token = TokenTree::token_alone(token::Interpolated(nt.clone()), sp);
232-
result.push(token);
230+
result
231+
.push(TokenTree::token_alone(token::Interpolated(nt.clone()), sp));
233232
}
234233
MatchedSeq(..) => {
235234
// We were unable to descend far enough. This is an error.

compiler/rustc_macros/src/serialize.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ fn decodable_body(
5959
})
6060
.collect();
6161
let message = format!(
62-
"invalid enum variant tag while decoding `{}`, expected 0..{}",
62+
"invalid enum variant tag while decoding `{}`, expected 0..{}, actual {{}}",
6363
ty_name,
6464
variants.len()
6565
);
6666
quote! {
6767
match ::rustc_serialize::Decoder::read_usize(__decoder) {
6868
#match_inner
69-
_ => panic!(#message),
69+
n => panic!(#message, n),
7070
}
7171
}
7272
}

compiler/rustc_parse/src/parser/expr.rs

+13-27
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,7 @@ impl<'a> Parser<'a> {
193193

194194
self.expected_tokens.push(TokenType::Operator);
195195
while let Some(op) = self.check_assoc_op() {
196-
// Adjust the span for interpolated LHS to point to the `$lhs` token
197-
// and not to what it refers to.
198-
let lhs_span = match self.prev_token.kind {
199-
TokenKind::Interpolated(..) => self.prev_token.span,
200-
_ => lhs.span,
201-
};
202-
196+
let lhs_span = self.interpolated_or_expr_span(&lhs);
203197
let cur_op_span = self.token.span;
204198
let restrictions = if op.node.is_assign_like() {
205199
self.restrictions & Restrictions::NO_STRUCT_LITERAL
@@ -626,8 +620,8 @@ impl<'a> Parser<'a> {
626620

627621
fn parse_expr_prefix_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> {
628622
self.bump();
629-
let expr = self.parse_expr_prefix(None);
630-
let (span, expr) = self.interpolated_or_expr_span(expr)?;
623+
let expr = self.parse_expr_prefix(None)?;
624+
let span = self.interpolated_or_expr_span(&expr);
631625
Ok((lo.to(span), expr))
632626
}
633627

@@ -702,20 +696,12 @@ impl<'a> Parser<'a> {
702696
self.parse_expr_unary(lo, UnOp::Not)
703697
}
704698

705-
/// Returns the span of expr, if it was not interpolated or the span of the interpolated token.
706-
fn interpolated_or_expr_span(
707-
&self,
708-
expr: PResult<'a, P<Expr>>,
709-
) -> PResult<'a, (Span, P<Expr>)> {
710-
expr.map(|e| {
711-
(
712-
match self.prev_token.kind {
713-
TokenKind::Interpolated(..) => self.prev_token.span,
714-
_ => e.span,
715-
},
716-
e,
717-
)
718-
})
699+
/// Returns the span of expr if it was not interpolated, or the span of the interpolated token.
700+
fn interpolated_or_expr_span(&self, expr: &Expr) -> Span {
701+
match self.prev_token.kind {
702+
TokenKind::Interpolated(..) => self.prev_token.span,
703+
_ => expr.span,
704+
}
719705
}
720706

721707
fn parse_assoc_op_cast(
@@ -898,8 +884,8 @@ impl<'a> Parser<'a> {
898884
self.parse_expr_prefix_range(None)
899885
} else {
900886
self.parse_expr_prefix(None)
901-
};
902-
let (hi, expr) = self.interpolated_or_expr_span(expr)?;
887+
}?;
888+
let hi = self.interpolated_or_expr_span(&expr);
903889
let span = lo.to(hi);
904890
if let Some(lt) = lifetime {
905891
self.error_remove_borrow_lifetime(span, lt.ident.span);
@@ -930,8 +916,8 @@ impl<'a> Parser<'a> {
930916
fn parse_expr_dot_or_call(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
931917
let attrs = self.parse_or_use_outer_attributes(attrs)?;
932918
self.collect_tokens_for_expr(attrs, |this, attrs| {
933-
let base = this.parse_expr_bottom();
934-
let (span, base) = this.interpolated_or_expr_span(base)?;
919+
let base = this.parse_expr_bottom()?;
920+
let span = this.interpolated_or_expr_span(&base);
935921
this.parse_expr_dot_or_call_with(base, span, attrs)
936922
})
937923
}

compiler/rustc_parse/src/parser/mod.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -1052,33 +1052,48 @@ impl<'a> Parser<'a> {
10521052
}
10531053

10541054
/// Look-ahead `dist` tokens of `self.token` and get access to that token there.
1055-
/// When `dist == 0` then the current token is looked at.
1055+
/// When `dist == 0` then the current token is looked at. `Eof` will be
1056+
/// returned if the look-ahead is any distance past the end of the tokens.
10561057
pub fn look_ahead<R>(&self, dist: usize, looker: impl FnOnce(&Token) -> R) -> R {
10571058
if dist == 0 {
10581059
return looker(&self.token);
10591060
}
10601061

1061-
let tree_cursor = &self.token_cursor.tree_cursor;
10621062
if let Some(&(_, delim, span)) = self.token_cursor.stack.last()
10631063
&& delim != Delimiter::Invisible
10641064
{
1065+
// We are not in the outermost token stream, and the token stream
1066+
// we are in has non-skipped delimiters. Look for skipped
1067+
// delimiters in the lookahead range.
1068+
let tree_cursor = &self.token_cursor.tree_cursor;
10651069
let all_normal = (0..dist).all(|i| {
10661070
let token = tree_cursor.look_ahead(i);
10671071
!matches!(token, Some(TokenTree::Delimited(_, Delimiter::Invisible, _)))
10681072
});
10691073
if all_normal {
1074+
// There were no skipped delimiters. Do lookahead by plain indexing.
10701075
return match tree_cursor.look_ahead(dist - 1) {
1071-
Some(tree) => match tree {
1072-
TokenTree::Token(token, _) => looker(token),
1073-
TokenTree::Delimited(dspan, delim, _) => {
1074-
looker(&Token::new(token::OpenDelim(*delim), dspan.open))
1076+
Some(tree) => {
1077+
// Indexing stayed within the current token stream.
1078+
match tree {
1079+
TokenTree::Token(token, _) => looker(token),
1080+
TokenTree::Delimited(dspan, delim, _) => {
1081+
looker(&Token::new(token::OpenDelim(*delim), dspan.open))
1082+
}
10751083
}
1076-
},
1077-
None => looker(&Token::new(token::CloseDelim(delim), span.close)),
1084+
}
1085+
None => {
1086+
// Indexing went past the end of the current token
1087+
// stream. Use the close delimiter, no matter how far
1088+
// ahead `dist` went.
1089+
looker(&Token::new(token::CloseDelim(delim), span.close))
1090+
}
10781091
};
10791092
}
10801093
}
10811094

1095+
// We are in a more complex case. Just clone the token cursor and use
1096+
// `next`, skipping delimiters as necessary. Slow but simple.
10821097
let mut cursor = self.token_cursor.clone();
10831098
let mut i = 0;
10841099
let mut token = Token::dummy();
@@ -1476,7 +1491,7 @@ pub enum FlatToken {
14761491
}
14771492

14781493
#[derive(Debug)]
1479-
pub enum NtOrTt {
1494+
pub enum ParseNtResult {
14801495
Nt(Nonterminal),
14811496
Tt(TokenTree),
14821497
}

0 commit comments

Comments
 (0)