Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove NtExpr and NtLiteral #138478

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions compiler/rustc_ast/src/ast_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,11 @@ impl HasTokens for Attribute {
impl HasTokens for Nonterminal {
fn tokens(&self) -> Option<&LazyAttrTokenStream> {
match self {
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens(),
Nonterminal::NtBlock(block) => block.tokens(),
}
}
fn tokens_mut(&mut self) -> Option<&mut Option<LazyAttrTokenStream>> {
match self {
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => expr.tokens_mut(),
Nonterminal::NtBlock(block) => block.tokens_mut(),
}
}
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -900,8 +900,6 @@ pub fn visit_token<T: MutVisitor>(vis: &mut T, t: &mut Token) {
fn visit_nonterminal<T: MutVisitor>(vis: &mut T, nt: &mut token::Nonterminal) {
match nt {
token::NtBlock(block) => vis.visit_block(block),
token::NtExpr(expr) => vis.visit_expr(expr),
token::NtLiteral(expr) => vis.visit_expr(expr),
}
}

Expand Down
71 changes: 23 additions & 48 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,16 +198,17 @@ impl Lit {
}
}

/// Keep this in sync with `Token::can_begin_literal_maybe_minus` excluding unary negation.
/// Keep this in sync with `Token::can_begin_literal_maybe_minus` and
/// `Parser::eat_token_lit` (excluding unary negation).
pub fn from_token(token: &Token) -> Option<Lit> {
match token.uninterpolate().kind {
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => Some(Lit::new(Bool, name, None)),
Literal(token_lit) => Some(token_lit),
Interpolated(ref nt)
if let NtExpr(expr) | NtLiteral(expr) = &**nt
&& let ast::ExprKind::Lit(token_lit) = expr.kind =>
{
Some(token_lit)
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Literal | MetaVarKind::Expr { .. },
))) => {
// Unreachable with the current test suite.
panic!("from_token metavar");
}
_ => None,
}
Expand Down Expand Up @@ -590,6 +591,9 @@ impl Token {
/// for which spans affect name resolution and edition checks.
/// Note that keywords are also identifiers, so they should use this
/// if they keep spans or perform edition checks.
//
// Note: `Parser::uninterpolated_token_span` may give better information
// than this method does.
pub fn uninterpolated_span(&self) -> Span {
match self.kind {
NtIdent(ident, _) | NtLifetime(ident, _) => ident.span,
Expand Down Expand Up @@ -642,12 +646,7 @@ impl Token {
PathSep | // global path
Lifetime(..) | // labeled loop
Pound => true, // expression attributes
Interpolated(ref nt) =>
matches!(&**nt,
NtBlock(..) |
NtExpr(..) |
NtLiteral(..)
),
Interpolated(ref nt) => matches!(&**nt, NtBlock(..)),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Block |
MetaVarKind::Expr { .. } |
Expand Down Expand Up @@ -677,11 +676,6 @@ impl Token {
Lt | // path (UFCS constant)
Shl => true, // path (double UFCS)
Or => matches!(pat_kind, PatWithOr), // leading vert `|` or-pattern
Interpolated(nt) =>
matches!(&**nt,
| NtExpr(..)
| NtLiteral(..)
),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Expr { .. } |
MetaVarKind::Literal |
Expand Down Expand Up @@ -724,7 +718,7 @@ impl Token {
match self.kind {
OpenDelim(Delimiter::Brace) | Literal(..) | Minus => true,
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)),
Interpolated(ref nt) => matches!(&**nt, NtBlock(..)),
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Expr { .. } | MetaVarKind::Block | MetaVarKind::Literal,
))) => true,
Expand Down Expand Up @@ -768,22 +762,12 @@ impl Token {
///
/// In other words, would this token be a valid start of `parse_literal_maybe_minus`?
///
/// Keep this in sync with and `Lit::from_token`, excluding unary negation.
/// Keep this in sync with `Lit::from_token` and `Parser::eat_token_lit`
/// (excluding unary negation).
pub fn can_begin_literal_maybe_minus(&self) -> bool {
match self.uninterpolate().kind {
Literal(..) | Minus => true,
Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
Interpolated(ref nt) => match &**nt {
NtLiteral(_) => true,
NtExpr(e) => match &e.kind {
ast::ExprKind::Lit(_) => true,
ast::ExprKind::Unary(ast::UnOp::Neg, e) => {
matches!(&e.kind, ast::ExprKind::Lit(_))
}
_ => false,
},
_ => false,
},
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind))) => match mv_kind {
MetaVarKind::Literal => true,
MetaVarKind::Expr { can_begin_literal_maybe_minus, .. } => {
Expand All @@ -798,14 +782,6 @@ impl Token {
pub fn can_begin_string_literal(&self) -> bool {
match self.uninterpolate().kind {
Literal(..) => true,
Interpolated(ref nt) => match &**nt {
NtLiteral(_) => true,
NtExpr(e) => match &e.kind {
ast::ExprKind::Lit(_) => true,
_ => false,
},
_ => false,
},
OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(mv_kind))) => match mv_kind {
MetaVarKind::Literal => true,
MetaVarKind::Expr { can_begin_string_literal, .. } => can_begin_string_literal,
Expand Down Expand Up @@ -869,19 +845,25 @@ impl Token {

/// Is this a pre-parsed expression dropped into the token stream
/// (which happens while parsing the result of macro expansion)?
pub fn is_whole_expr(&self) -> bool {
pub fn is_metavar_expr(&self) -> bool {
#[allow(irrefutable_let_patterns)] // FIXME: temporary
if let Interpolated(nt) = &self.kind
&& let NtExpr(_) | NtLiteral(_) | NtBlock(_) = &**nt
&& let NtBlock(_) = &**nt
{
true
} else if matches!(
self.is_metavar_seq(),
Some(MetaVarKind::Expr { .. } | MetaVarKind::Literal | MetaVarKind::Path)
) {
true
} else {
matches!(self.is_metavar_seq(), Some(MetaVarKind::Path))
}
}

/// Is the token an interpolated block (`$b:block`)?
pub fn is_whole_block(&self) -> bool {
#[allow(irrefutable_let_patterns)] // FIXME: temporary
if let Interpolated(nt) = &self.kind
&& let NtBlock(..) = &**nt
{
Expand Down Expand Up @@ -1105,8 +1087,6 @@ pub enum NtExprKind {
/// For interpolation during macro expansion.
pub enum Nonterminal {
NtBlock(P<ast::Block>),
NtExpr(P<ast::Expr>),
NtLiteral(P<ast::Expr>),
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
Expand Down Expand Up @@ -1196,15 +1176,12 @@ impl Nonterminal {
pub fn use_span(&self) -> Span {
match self {
NtBlock(block) => block.span,
NtExpr(expr) | NtLiteral(expr) => expr.span,
}
}

pub fn descr(&self) -> &'static str {
match self {
NtBlock(..) => "block",
NtExpr(..) => "expression",
NtLiteral(..) => "literal",
}
}
}
Expand All @@ -1223,8 +1200,6 @@ impl fmt::Debug for Nonterminal {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
NtBlock(..) => f.pad("NtBlock(..)"),
NtExpr(..) => f.pad("NtExpr(..)"),
NtLiteral(..) => f.pad("NtLiteral(..)"),
}
}
}
Expand All @@ -1247,7 +1222,7 @@ mod size_asserts {
// tidy-alphabetical-start
static_assert_size!(Lit, 12);
static_assert_size!(LitKind, 2);
static_assert_size!(Nonterminal, 16);
static_assert_size!(Nonterminal, 8);
static_assert_size!(Token, 24);
static_assert_size!(TokenKind, 16);
// tidy-alphabetical-end
Expand Down
62 changes: 39 additions & 23 deletions compiler/rustc_ast/src/tokenstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,35 +233,52 @@ fn attrs_and_tokens_to_token_trees(

// Insert inner attribute tokens.
if !inner_attrs.is_empty() {
let mut found = false;
// Check the last two trees (to account for a trailing semi)
for tree in res.iter_mut().rev().take(2) {
if let TokenTree::Delimited(span, spacing, delim, delim_tokens) = tree {
// Inner attributes are only supported on extern blocks, functions,
// impls, and modules. All of these have their inner attributes
// placed at the beginning of the rightmost outermost braced group:
// e.g. fn foo() { #![my_attr] }
//
// Therefore, we can insert them back into the right location
// without needing to do any extra position tracking.
//
// Note: Outline modules are an exception - they can
// have attributes like `#![my_attr]` at the start of a file.
// Support for custom attributes in this position is not
// properly implemented - we always synthesize fake tokens,
// so we never reach this code.
let found = insert_inner_attrs(inner_attrs, res);
assert!(found, "Failed to find trailing delimited group in: {res:?}");
}

// Inner attributes are only supported on blocks, functions, impls, and
// modules. All of these have their inner attributes placed at the
// beginning of the rightmost outermost braced group:
// e.g. `fn foo() { #![my_attr] }`. (Note: the braces may be within
// invisible delimiters.)
//
// Therefore, we can insert them back into the right location without
// needing to do any extra position tracking.
//
// Note: Outline modules are an exception - they can have attributes like
// `#![my_attr]` at the start of a file. Support for custom attributes in
// this position is not properly implemented - we always synthesize fake
// tokens, so we never reach this code.
fn insert_inner_attrs(inner_attrs: &[Attribute], tts: &mut Vec<TokenTree>) -> bool {
for tree in tts.iter_mut().rev() {
if let TokenTree::Delimited(span, spacing, Delimiter::Brace, stream) = tree {
// Found it: the rightmost, outermost braced group.
let mut tts = vec![];
for inner_attr in inner_attrs {
tts.extend(inner_attr.token_trees());
}
tts.extend(delim_tokens.0.iter().cloned());
tts.extend(stream.0.iter().cloned());
let stream = TokenStream::new(tts);
*tree = TokenTree::Delimited(*span, *spacing, *delim, stream);
found = true;
break;
*tree = TokenTree::Delimited(*span, *spacing, Delimiter::Brace, stream);
return true;
} else if let TokenTree::Delimited(span, spacing, Delimiter::Invisible(src), stream) =
tree
{
// Recurse inside invisible delimiters.
let mut vec: Vec<_> = stream.iter().cloned().collect();
if insert_inner_attrs(inner_attrs, &mut vec) {
*tree = TokenTree::Delimited(
*span,
*spacing,
Delimiter::Invisible(*src),
TokenStream::new(vec),
);
return true;
}
}
}
assert!(found, "Failed to find trailing delimited group in: {res:?}");
false
}
}

Expand Down Expand Up @@ -462,7 +479,6 @@ impl TokenStream {
pub fn from_nonterminal_ast(nt: &Nonterminal) -> TokenStream {
match nt {
Nonterminal::NtBlock(block) => TokenStream::from_ast(block),
Nonterminal::NtExpr(expr) | Nonterminal::NtLiteral(expr) => TokenStream::from_ast(expr),
}
}

Expand Down
35 changes: 28 additions & 7 deletions compiler/rustc_expand/src/mbe/transcribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ use std::sync::Arc;

use rustc_ast::mut_visit::{self, MutVisitor};
use rustc_ast::token::{
self, Delimiter, IdentIsRaw, InvisibleOrigin, Lit, LitKind, MetaVarKind, Nonterminal, Token,
TokenKind,
self, Delimiter, IdentIsRaw, InvisibleOrigin, Lit, LitKind, MetaVarKind, Token, TokenKind,
};
use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
use rustc_ast::{ExprKind, StmtKind, TyKind};
use rustc_ast::{ExprKind, StmtKind, TyKind, UnOp};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Diag, DiagCtxtHandle, PResult, pluralize};
use rustc_parse::lexer::nfc_normalize;
Expand Down Expand Up @@ -340,6 +339,30 @@ pub(super) fn transcribe<'a>(
MetaVarKind::Pat(*pat_kind),
TokenStream::from_ast(pat),
),
MatchedSingle(ParseNtResult::Expr(expr, kind)) => {
let (can_begin_literal_maybe_minus, can_begin_string_literal) =
match &expr.kind {
ExprKind::Lit(_) => (true, true),
ExprKind::Unary(UnOp::Neg, e)
if matches!(&e.kind, ExprKind::Lit(_)) =>
{
(true, false)
}
_ => (false, false),
};
mk_delimited(
expr.span,
MetaVarKind::Expr {
kind: *kind,
can_begin_literal_maybe_minus,
can_begin_string_literal,
},
TokenStream::from_ast(expr),
)
}
MatchedSingle(ParseNtResult::Literal(lit)) => {
mk_delimited(lit.span, MetaVarKind::Literal, TokenStream::from_ast(lit))
}
MatchedSingle(ParseNtResult::Ty(ty)) => {
let is_path = matches!(&ty.kind, TyKind::Path(None, _path));
mk_delimited(
Expand Down Expand Up @@ -869,10 +892,8 @@ fn extract_symbol_from_pnr<'a>(
},
_,
)) => Ok(*symbol),
ParseNtResult::Nt(nt)
if let Nonterminal::NtLiteral(expr) = &**nt
&& let ExprKind::Lit(Lit { kind: LitKind::Str, symbol, suffix: None }) =
&expr.kind =>
ParseNtResult::Literal(expr)
if let ExprKind::Lit(Lit { kind: LitKind::Str, symbol, suffix: None }) = &expr.kind =>
{
Ok(*symbol)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,7 @@ parse_unexpected_parentheses_in_match_arm_pattern = unexpected parentheses surro
parse_unexpected_self_in_generic_parameters = unexpected keyword `Self` in generic parameters
.note = you cannot use `Self` as a generic parameter because it is reserved for associated items

parse_unexpected_token_after_dot = unexpected token: `{$actual}`
parse_unexpected_token_after_dot = unexpected token: {$actual}

parse_unexpected_token_after_label = expected `while`, `for`, `loop` or `{"{"}` after a label
.suggestion_remove_label = consider removing the label
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1714,10 +1714,10 @@ pub(crate) struct SelfArgumentPointer {

#[derive(Diagnostic)]
#[diag(parse_unexpected_token_after_dot)]
pub(crate) struct UnexpectedTokenAfterDot<'a> {
pub(crate) struct UnexpectedTokenAfterDot {
#[primary_span]
pub span: Span,
pub actual: Cow<'a, str>,
pub actual: String,
}

#[derive(Diagnostic)]
Expand Down
Loading
Loading