From a3fce72a27ee41077c3752851ff778f886f0a4fa Mon Sep 17 00:00:00 2001 From: Lieselotte <52315535+she3py@users.noreply.github.com> Date: Sun, 25 Feb 2024 22:22:09 +0100 Subject: [PATCH] Add `ast::ExprKind::Dummy` --- compiler/rustc_ast/src/ast.rs | 18 ++++-------------- compiler/rustc_ast/src/mut_visit.rs | 4 ++-- compiler/rustc_ast/src/util/classify.rs | 3 ++- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 6 ++++++ compiler/rustc_ast_lowering/src/pat.rs | 3 ++- .../rustc_ast_pretty/src/pprust/state/expr.rs | 5 +++++ .../rustc_builtin_macros/src/assert/context.rs | 1 + compiler/rustc_builtin_macros/src/concat.rs | 1 + .../rustc_builtin_macros/src/concat_bytes.rs | 1 + compiler/rustc_expand/src/base.rs | 3 +++ compiler/rustc_parse/src/parser/expr.rs | 3 ++- compiler/rustc_parse/src/parser/pat.rs | 2 +- compiler/rustc_passes/src/hir_stats.rs | 2 +- src/tools/clippy/clippy_utils/src/ast_utils.rs | 1 + src/tools/clippy/clippy_utils/src/sugg.rs | 3 ++- src/tools/rustfmt/src/expr.rs | 2 +- src/tools/rustfmt/src/utils.rs | 1 + 18 files changed, 37 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 3fdb2a2225a..b30324c7666 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1296,23 +1296,10 @@ pub fn precedence(&self) -> ExprPrecedence { ExprKind::Yeet(..) => ExprPrecedence::Yeet, ExprKind::FormatArgs(..) => ExprPrecedence::FormatArgs, ExprKind::Become(..) => ExprPrecedence::Become, - ExprKind::Err => ExprPrecedence::Err, + ExprKind::Err | ExprKind::Dummy => ExprPrecedence::Err, } } - pub fn take(&mut self) -> Self { - mem::replace( - self, - Expr { - id: DUMMY_NODE_ID, - kind: ExprKind::Err, - span: DUMMY_SP, - attrs: AttrVec::new(), - tokens: None, - }, - ) - } - /// To a first-order approximation, is this a pattern? pub fn is_approximately_pattern(&self) -> bool { matches!( @@ -1532,6 +1519,9 @@ pub enum ExprKind { /// Placeholder for an expression that wasn't syntactically well formed in some way. Err, + + /// Acts as a null expression. Lowering it will always emit a bug. + Dummy, } /// Used to differentiate between `for` loops and `for await` loops. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index c42c4199973..b2f3bb303de 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1526,7 +1526,7 @@ pub fn noop_visit_expr( } ExprKind::Try(expr) => vis.visit_expr(expr), ExprKind::TryBlock(body) => vis.visit_block(body), - ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {} + ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err | ExprKind::Dummy => {} } vis.visit_id(id); vis.visit_span(span); @@ -1642,7 +1642,7 @@ impl DummyAstNode for Expr { fn dummy() -> Self { Expr { id: DUMMY_NODE_ID, - kind: ExprKind::Err, + kind: ExprKind::Dummy, span: Default::default(), attrs: Default::default(), tokens: Default::default(), diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 098b8f2d6d0..e70a75622e6 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -89,7 +89,8 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> { | Paren(_) | Try(_) | Yeet(None) - | Err => break None, + | Err + | Dummy => break None, } } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ecf379cc240..ab3d9b49633 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -1063,7 +1063,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V } ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)), ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)), - ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {} + ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err | ExprKind::Dummy => {} } visitor.visit_expr_post(expression) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index aafa99b3aa6..5d33a7a9142 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -14,6 +14,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; +use rustc_middle::span_bug; use rustc_session::errors::report_lit_error; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -331,6 +332,11 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> { ExprKind::Err => { hir::ExprKind::Err(self.dcx().span_delayed_bug(e.span, "lowered ExprKind::Err")) } + + ExprKind::Dummy => { + span_bug!(e.span, "lowered ExprKind::Dummy") + } + ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr), ExprKind::Paren(_) | ExprKind::ForLoop { .. } => { diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index c097feb6b34..755b073b2c3 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -331,7 +331,8 @@ fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir hir ExprKind::Lit(..) | ExprKind::ConstBlock(..) | ExprKind::IncludedBytes(..) - | ExprKind::Err => {} + | ExprKind::Err + | ExprKind::Dummy => {} ExprKind::Path(..) if allow_paths => {} ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} _ => { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index ff154a009ed..0f9fe89402b 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -898,6 +898,11 @@ pub(super) fn print_expr_outer_attr_style( self.word("/*ERROR*/"); self.pclose() } + ast::ExprKind::Dummy => { + self.popen(); + self.word("/*DUMMY*/"); + self.pclose(); + } } self.ann.post(self, AnnNode::Expr(expr)); diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 01821ee833f..7737041090b 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -303,6 +303,7 @@ fn manage_cond_expr(&mut self, expr: &mut P) { | ExprKind::Closure(_) | ExprKind::ConstBlock(_) | ExprKind::Continue(_) + | ExprKind::Dummy | ExprKind::Err | ExprKind::Field(_, _) | ExprKind::ForLoop { .. } diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs index 795161e65d8..691142c03ed 100644 --- a/compiler/rustc_builtin_macros/src/concat.rs +++ b/compiler/rustc_builtin_macros/src/concat.rs @@ -68,6 +68,7 @@ pub fn expand_concat( ast::ExprKind::Err => { has_errors = true; } + ast::ExprKind::Dummy => cx.dcx().span_bug(e.span, "concatenating `ExprKind::Dummy`"), _ => { missing_literal.push(e.span); } diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs index 3ef8cb7bffe..8ce004586ce 100644 --- a/compiler/rustc_builtin_macros/src/concat_bytes.rs +++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs @@ -176,6 +176,7 @@ pub fn expand_concat_bytes( ast::ExprKind::Err => { has_errors = true; } + ast::ExprKind::Dummy => cx.dcx().span_bug(e.span, "concatenating `ExprKind::Dummy`"), _ => { missing_literals.push(e.span); } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 1c8d18bec65..762d6745341 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1279,6 +1279,9 @@ pub fn expr_to_spanned_string<'a>( _ => Some((cx.dcx().struct_span_err(expr.span, err_msg), false)), }, ast::ExprKind::Err => None, + ast::ExprKind::Dummy => { + cx.dcx().span_bug(expr.span, "tried to get a string literal from `ExprKind::Dummy`") + } _ => Some((cx.dcx().struct_span_err(expr.span, err_msg), false)), }) } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 1ad637451b1..89f28777bff 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3949,7 +3949,8 @@ fn visit_expr(&mut self, e: &mut P) { | ExprKind::Become(_) | ExprKind::IncludedBytes(_) | ExprKind::FormatArgs(_) - | ExprKind::Err => { + | ExprKind::Err + | ExprKind::Dummy => { // These would forbid any let expressions they contain already. } } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 2ede19b11e0..c82b44ac6e1 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -388,7 +388,7 @@ fn maybe_recover_trailing_expr( // Parse `?`, `.f`, `(arg0, arg1, ...)` or `[expr]` until they've all been eaten. if let Ok(expr) = snapshot .parse_expr_dot_or_call_with( - self.mk_expr_err(pat_span), // equivalent to transforming the parsed pattern into an `Expr` + self.mk_expr(pat_span, ExprKind::Dummy), // equivalent to transforming the parsed pattern into an `Expr` pat_span, AttrVec::new(), ) diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 96429bb7788..be6ba585d20 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -589,7 +589,7 @@ fn visit_expr(&mut self, e: &'v ast::Expr) { If, While, ForLoop, Loop, Match, Closure, Block, Await, TryBlock, Assign, AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret, InlineAsm, FormatArgs, OffsetOf, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet, - Become, IncludedBytes, Gen, Err + Become, IncludedBytes, Gen, Err, Dummy ] ); ast_visit::walk_expr(self, e) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 0467a8a6570..81a26a12009 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -144,6 +144,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { (Paren(l), _) => eq_expr(l, r), (_, Paren(r)) => eq_expr(l, r), (Err, Err) => true, + (Dummy, _) | (_, Dummy) => unreachable!("comparing `ExprKind::Dummy`"), (Try(l), Try(r)) | (Await(l, _), Await(r, _)) => eq_expr(l, r), (Array(l), Array(r)) => over(l, r, |l, r| eq_expr(l, r)), (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)), diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index b355e66b7b1..7b1b0388b29 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -222,7 +222,8 @@ pub fn ast( | ast::ExprKind::Array(..) | ast::ExprKind::While(..) | ast::ExprKind::Await(..) - | ast::ExprKind::Err => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0), + | ast::ExprKind::Err + | ast::ExprKind::Dummy => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0), ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::HalfOpen) => Sugg::BinOp( AssocOp::DotDot, lhs.as_ref().map_or("".into(), |lhs| { diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index 4b86c2acdc5..d46d7c53bdb 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -404,7 +404,7 @@ fn needs_space_after_range(rhs: &ast::Expr) -> bool { // These do not occur in the AST because macros aren't expanded. unreachable!() } - ast::ExprKind::Err => None, + ast::ExprKind::Err | ast::ExprKind::Dummy => None, }; expr_rw diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index 642b6603b1e..b6b37e492e9 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -497,6 +497,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::Break(..) | ast::ExprKind::Cast(..) | ast::ExprKind::Continue(..) + | ast::ExprKind::Dummy | ast::ExprKind::Err | ast::ExprKind::Field(..) | ast::ExprKind::IncludedBytes(..)