Skip to content

Commit 8b13210

Browse files
authored
Rollup merge of #122752 - nnethercote:Interpolated-cleanups, r=petrochenkov
Interpolated cleanups Various cleanups I made while working on attempts to remove `Interpolated`, that are worth merging now. Best reviewed one commit at a time. r? `@petrochenkov`
2 parents 40c972e + 82a609f commit 8b13210

File tree

17 files changed

+129
-138
lines changed

17 files changed

+129
-138
lines changed

compiler/rustc_ast/src/token.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl Lit {
105105
}
106106
}
107107

108-
/// Keep this in sync with `Token::can_begin_literal_or_bool` excluding unary negation.
108+
/// Keep this in sync with `Token::can_begin_literal_maybe_minus` excluding unary negation.
109109
pub fn from_token(token: &Token) -> Option<Lit> {
110110
match token.uninterpolate().kind {
111111
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => Some(Lit::new(Bool, name, None)),
@@ -664,7 +664,7 @@ impl Token {
664664
}
665665

666666
/// Returns `true` if the token is an interpolated path.
667-
fn is_path(&self) -> bool {
667+
fn is_whole_path(&self) -> bool {
668668
if let Interpolated(nt) = &self.kind
669669
&& let NtPath(..) = &nt.0
670670
{
@@ -710,7 +710,7 @@ impl Token {
710710
pub fn is_path_start(&self) -> bool {
711711
self == &ModSep
712712
|| self.is_qpath_start()
713-
|| self.is_path()
713+
|| self.is_whole_path()
714714
|| self.is_path_segment_keyword()
715715
|| self.is_ident() && !self.is_reserved_ident()
716716
}

compiler/rustc_ast/src/tokenstream.rs

+1-12
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,7 @@ use smallvec::{smallvec, SmallVec};
2828
use std::borrow::Cow;
2929
use std::{cmp, fmt, iter};
3030

31-
/// When the main Rust parser encounters a syntax-extension invocation, it
32-
/// parses the arguments to the invocation as a token tree. This is a very
33-
/// loose structure, such that all sorts of different AST fragments can
34-
/// be passed to syntax extensions using a uniform type.
35-
///
36-
/// If the syntax extension is an MBE macro, it will attempt to match its
37-
/// LHS token tree against the provided token tree, and if it finds a
38-
/// match, will transcribe the RHS token tree, splicing in any captured
39-
/// `macro_parser::matched_nonterminals` into the `SubstNt`s it finds.
40-
///
41-
/// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
42-
/// Nothing special happens to misnamed or misplaced `SubstNt`s.
31+
/// Part of a `TokenStream`.
4332
#[derive(Debug, Clone, PartialEq, Encodable, Decodable, HashStable_Generic)]
4433
pub enum TokenTree {
4534
/// A single token. Should never be `OpenDelim` or `CloseDelim`, because

compiler/rustc_expand/src/mbe/macro_parser.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -392,12 +392,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize {
392392
#[derive(Debug, Clone)]
393393
pub(crate) enum NamedMatch {
394394
MatchedSeq(Vec<NamedMatch>),
395-
396-
// A metavar match of type `tt`.
397-
MatchedTokenTree(rustc_ast::tokenstream::TokenTree),
398-
399-
// A metavar match of any type other than `tt`.
400-
MatchedNonterminal(Lrc<(Nonterminal, rustc_span::Span)>),
395+
MatchedSingle(ParseNtResult<Lrc<(Nonterminal, Span)>>),
401396
}
402397

403398
/// Performs a token equality check, ignoring syntax context (that is, an unhygienic comparison)
@@ -691,11 +686,11 @@ impl TtParser {
691686
}
692687
Ok(nt) => nt,
693688
};
694-
let m = match nt {
695-
ParseNtResult::Nt(nt) => MatchedNonterminal(Lrc::new((nt, span))),
696-
ParseNtResult::Tt(tt) => MatchedTokenTree(tt),
697-
};
698-
mp.push_match(next_metavar, seq_depth, m);
689+
mp.push_match(
690+
next_metavar,
691+
seq_depth,
692+
MatchedSingle(nt.map_nt(|nt| (Lrc::new((nt, span))))),
693+
);
699694
mp.idx += 1;
700695
} else {
701696
unreachable!()

compiler/rustc_expand/src/mbe/macro_rules.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::mbe;
55
use crate::mbe::diagnostics::{annotate_doc_comment, parse_failure_msg};
66
use crate::mbe::macro_check;
77
use crate::mbe::macro_parser::{Error, ErrorReported, Failure, Success, TtParser};
8-
use crate::mbe::macro_parser::{MatchedSeq, MatchedTokenTree, MatcherLoc};
8+
use crate::mbe::macro_parser::{MatcherLoc, NamedMatch::*};
99
use crate::mbe::transcribe::transcribe;
1010

1111
use ast::token::IdentIsRaw;
@@ -22,7 +22,7 @@ use rustc_lint_defs::builtin::{
2222
RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
2323
};
2424
use rustc_lint_defs::BuiltinLintDiag;
25-
use rustc_parse::parser::{Parser, Recovery};
25+
use rustc_parse::parser::{ParseNtResult, Parser, Recovery};
2626
use rustc_session::parse::ParseSess;
2727
use rustc_session::Session;
2828
use rustc_span::edition::Edition;
@@ -479,7 +479,7 @@ pub fn compile_declarative_macro(
479479
MatchedSeq(s) => s
480480
.iter()
481481
.map(|m| {
482-
if let MatchedTokenTree(tt) = m {
482+
if let MatchedSingle(ParseNtResult::Tt(tt)) = m {
483483
let tt = mbe::quoted::parse(
484484
&TokenStream::new(vec![tt.clone()]),
485485
true,
@@ -505,7 +505,7 @@ pub fn compile_declarative_macro(
505505
MatchedSeq(s) => s
506506
.iter()
507507
.map(|m| {
508-
if let MatchedTokenTree(tt) = m {
508+
if let MatchedSingle(ParseNtResult::Tt(tt)) = m {
509509
return mbe::quoted::parse(
510510
&TokenStream::new(vec![tt.clone()]),
511511
false,

compiler/rustc_expand/src/mbe/transcribe.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ use crate::errors::{
33
CountRepetitionMisplaced, MetaVarExprUnrecognizedVar, MetaVarsDifSeqMatchers, MustRepeatOnce,
44
NoSyntaxVarsExprRepeat, VarStillRepeating,
55
};
6-
use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, MatchedTokenTree, NamedMatch};
6+
use crate::mbe::macro_parser::{NamedMatch, NamedMatch::*};
77
use crate::mbe::{self, KleeneOp, MetaVarExpr};
88
use rustc_ast::mut_visit::{self, MutVisitor};
99
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
1010
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
1111
use rustc_data_structures::fx::FxHashMap;
12-
use rustc_errors::Diag;
13-
use rustc_errors::{pluralize, PResult};
12+
use rustc_errors::{pluralize, Diag, PResult};
13+
use rustc_parse::parser::ParseNtResult;
1414
use rustc_span::hygiene::{LocalExpnId, Transparency};
1515
use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent};
1616
use rustc_span::{with_metavar_spans, Span, SyntaxContext};
@@ -250,26 +250,25 @@ pub(super) fn transcribe<'a>(
250250
// the meta-var.
251251
let ident = MacroRulesNormalizedIdent::new(original_ident);
252252
if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
253-
match cur_matched {
254-
MatchedTokenTree(tt) => {
253+
let tt = match cur_matched {
254+
MatchedSingle(ParseNtResult::Tt(tt)) => {
255255
// `tt`s are emitted into the output stream directly as "raw tokens",
256256
// without wrapping them into groups.
257-
let tt = maybe_use_metavar_location(cx, &stack, sp, tt, &mut marker);
258-
result.push(tt);
257+
maybe_use_metavar_location(cx, &stack, sp, tt, &mut marker)
259258
}
260-
MatchedNonterminal(nt) => {
259+
MatchedSingle(ParseNtResult::Nt(nt)) => {
261260
// Other variables are emitted into the output stream as groups with
262261
// `Delimiter::Invisible` to maintain parsing priorities.
263262
// `Interpolated` is currently used for such groups in rustc parser.
264263
marker.visit_span(&mut sp);
265-
result
266-
.push(TokenTree::token_alone(token::Interpolated(nt.clone()), sp));
264+
TokenTree::token_alone(token::Interpolated(nt.clone()), sp)
267265
}
268266
MatchedSeq(..) => {
269267
// We were unable to descend far enough. This is an error.
270268
return Err(cx.dcx().create_err(VarStillRepeating { span: sp, ident }));
271269
}
272-
}
270+
};
271+
result.push(tt)
273272
} else {
274273
// If we aren't able to match the meta-var, we push it back into the result but
275274
// with modified syntax context. (I believe this supports nested macros).
@@ -424,7 +423,7 @@ fn lookup_cur_matched<'a>(
424423
interpolations.get(&ident).map(|mut matched| {
425424
for &(idx, _) in repeats {
426425
match matched {
427-
MatchedTokenTree(_) | MatchedNonterminal(_) => break,
426+
MatchedSingle(_) => break,
428427
MatchedSeq(ads) => matched = ads.get(idx).unwrap(),
429428
}
430429
}
@@ -514,7 +513,7 @@ fn lockstep_iter_size(
514513
let name = MacroRulesNormalizedIdent::new(*name);
515514
match lookup_cur_matched(name, interpolations, repeats) {
516515
Some(matched) => match matched {
517-
MatchedTokenTree(_) | MatchedNonterminal(_) => LockstepIterSize::Unconstrained,
516+
MatchedSingle(_) => LockstepIterSize::Unconstrained,
518517
MatchedSeq(ads) => LockstepIterSize::Constraint(ads.len(), name),
519518
},
520519
_ => LockstepIterSize::Unconstrained,
@@ -557,7 +556,7 @@ fn count_repetitions<'a>(
557556
// (or at the top-level of `matched` if no depth is given).
558557
fn count<'a>(depth_curr: usize, depth_max: usize, matched: &NamedMatch) -> PResult<'a, usize> {
559558
match matched {
560-
MatchedTokenTree(_) | MatchedNonterminal(_) => Ok(1),
559+
MatchedSingle(_) => Ok(1),
561560
MatchedSeq(named_matches) => {
562561
if depth_curr == depth_max {
563562
Ok(named_matches.len())
@@ -571,7 +570,7 @@ fn count_repetitions<'a>(
571570
/// Maximum depth
572571
fn depth(counter: usize, matched: &NamedMatch) -> usize {
573572
match matched {
574-
MatchedTokenTree(_) | MatchedNonterminal(_) => counter,
573+
MatchedSingle(_) => counter,
575574
MatchedSeq(named_matches) => {
576575
let rslt = counter + 1;
577576
if let Some(elem) = named_matches.first() { depth(rslt, elem) } else { rslt }
@@ -599,7 +598,7 @@ fn count_repetitions<'a>(
599598
}
600599
}
601600

602-
if let MatchedTokenTree(_) | MatchedNonterminal(_) = matched {
601+
if let MatchedSingle(_) = matched {
603602
return Err(cx.dcx().create_err(CountRepetitionMisplaced { span: sp.entire() }));
604603
}
605604

compiler/rustc_parse/messages.ftl

-2
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,6 @@ parse_invalid_dyn_keyword = invalid `dyn` keyword
390390
parse_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else`
391391
parse_invalid_identifier_with_leading_number = identifiers cannot start with a number
392392
393-
parse_invalid_interpolated_expression = invalid interpolated expression
394-
395393
parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid
396394
.label = invalid suffix `{$suffix}`
397395
.tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases

compiler/rustc_parse/src/errors.rs

-7
Original file line numberDiff line numberDiff line change
@@ -850,13 +850,6 @@ pub(crate) struct StructLiteralNotAllowedHereSugg {
850850
pub right: Span,
851851
}
852852

853-
#[derive(Diagnostic)]
854-
#[diag(parse_invalid_interpolated_expression)]
855-
pub(crate) struct InvalidInterpolatedExpression {
856-
#[primary_span]
857-
pub span: Span,
858-
}
859-
860853
#[derive(Diagnostic)]
861854
#[diag(parse_invalid_literal_suffix_on_tuple_index)]
862855
pub(crate) struct InvalidLiteralSuffixOnTupleIndex {

compiler/rustc_parse/src/parser/attr.rs

+17-30
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ use crate::errors::{
33
SuffixedLiteralInAttribute,
44
};
55
use crate::fluent_generated as fluent;
6+
use crate::maybe_whole;
67

78
use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle};
89
use rustc_ast as ast;
910
use rustc_ast::attr;
10-
use rustc_ast::token::{self, Delimiter, Nonterminal};
11+
use rustc_ast::token::{self, Delimiter};
1112
use rustc_errors::{codes::*, Diag, PResult};
1213
use rustc_span::{sym, BytePos, Span};
1314
use thin_vec::ThinVec;
@@ -251,25 +252,15 @@ impl<'a> Parser<'a> {
251252
/// PATH `=` UNSUFFIXED_LIT
252253
/// The delimiters or `=` are still put into the resulting token stream.
253254
pub fn parse_attr_item(&mut self, capture_tokens: bool) -> PResult<'a, ast::AttrItem> {
254-
let item = match &self.token.kind {
255-
token::Interpolated(nt) => match &nt.0 {
256-
Nonterminal::NtMeta(item) => Some(item.clone().into_inner()),
257-
_ => None,
258-
},
259-
_ => None,
255+
maybe_whole!(self, NtMeta, |attr| attr.into_inner());
256+
257+
let do_parse = |this: &mut Self| {
258+
let path = this.parse_path(PathStyle::Mod)?;
259+
let args = this.parse_attr_args()?;
260+
Ok(ast::AttrItem { path, args, tokens: None })
260261
};
261-
Ok(if let Some(item) = item {
262-
self.bump();
263-
item
264-
} else {
265-
let do_parse = |this: &mut Self| {
266-
let path = this.parse_path(PathStyle::Mod)?;
267-
let args = this.parse_attr_args()?;
268-
Ok(ast::AttrItem { path, args, tokens: None })
269-
};
270-
// Attr items don't have attributes
271-
if capture_tokens { self.collect_tokens_no_attrs(do_parse) } else { do_parse(self) }?
272-
})
262+
// Attr items don't have attributes
263+
if capture_tokens { self.collect_tokens_no_attrs(do_parse) } else { do_parse(self) }
273264
}
274265

275266
/// Parses attributes that appear after the opening of an item. These should
@@ -371,22 +362,18 @@ impl<'a> Parser<'a> {
371362
/// meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
372363
/// ```
373364
pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> {
374-
let nt_meta = match &self.token.kind {
375-
token::Interpolated(nt) => match &nt.0 {
376-
token::NtMeta(e) => Some(e.clone()),
377-
_ => None,
378-
},
379-
_ => None,
380-
};
381-
382-
if let Some(item) = nt_meta {
383-
match item.meta(item.path.span) {
365+
// We can't use `maybe_whole` here because it would bump in the `None`
366+
// case, which we don't want.
367+
if let token::Interpolated(nt) = &self.token.kind
368+
&& let token::NtMeta(attr_item) = &nt.0
369+
{
370+
match attr_item.meta(attr_item.path.span) {
384371
Some(meta) => {
385372
self.bump();
386373
return Ok(meta);
387374
}
388375
None => self.unexpected()?,
389-
};
376+
}
390377
}
391378

392379
let lo = self.token.span;

compiler/rustc_parse/src/parser/expr.rs

-10
Original file line numberDiff line numberDiff line change
@@ -2053,16 +2053,6 @@ impl<'a> Parser<'a> {
20532053
&mut self,
20542054
mk_lit_char: impl FnOnce(Symbol, Span) -> L,
20552055
) -> PResult<'a, L> {
2056-
if let token::Interpolated(nt) = &self.token.kind
2057-
&& let token::NtExpr(e) | token::NtLiteral(e) = &nt.0
2058-
&& matches!(e.kind, ExprKind::Err(_))
2059-
{
2060-
let mut err = self
2061-
.dcx()
2062-
.create_err(errors::InvalidInterpolatedExpression { span: self.token.span });
2063-
err.downgrade_to_delayed_bug();
2064-
return Err(err);
2065-
}
20662056
let token = self.token.clone();
20672057
let err = |self_: &Self| {
20682058
let msg = format!("unexpected token: {}", super::token_descr(&token));

compiler/rustc_parse/src/parser/item.rs

+4-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use super::{
66
};
77
use crate::errors::{self, MacroExpandsToAdtField};
88
use crate::fluent_generated as fluent;
9+
use crate::maybe_whole;
910
use ast::token::IdentIsRaw;
1011
use rustc_ast::ast::*;
1112
use rustc_ast::ptr::P;
@@ -115,17 +116,10 @@ impl<'a> Parser<'a> {
115116
fn_parse_mode: FnParseMode,
116117
force_collect: ForceCollect,
117118
) -> PResult<'a, Option<Item>> {
118-
// Don't use `maybe_whole` so that we have precise control
119-
// over when we bump the parser
120-
if let token::Interpolated(nt) = &self.token.kind
121-
&& let token::NtItem(item) = &nt.0
122-
{
123-
let mut item = item.clone();
124-
self.bump();
125-
119+
maybe_whole!(self, NtItem, |item| {
126120
attrs.prepend_to_nt_inner(&mut item.attrs);
127-
return Ok(Some(item.into_inner()));
128-
};
121+
Some(item.into_inner())
122+
});
129123

130124
let item =
131125
self.collect_tokens_trailing_token(attrs, force_collect, |this: &mut Self, attrs| {

0 commit comments

Comments
 (0)