diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 7c19559ed91f5..35c23e4d457d5 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -930,6 +930,7 @@ pub struct Stmt { impl Stmt { pub fn tokens(&self) -> Option<&LazyTokenStream> { match self.kind { + StmtKind::LetElse(ref let_else) => let_else.tokens.as_ref(), StmtKind::Local(ref local) => local.tokens.as_ref(), StmtKind::Item(ref item) => item.tokens.as_ref(), StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => expr.tokens.as_ref(), @@ -978,6 +979,8 @@ impl Stmt { #[derive(Clone, Encodable, Decodable, Debug)] pub enum StmtKind { + /// See [`LetElse`]. + LetElse(P), /// A local (let) binding. Local(P), /// An item definition. @@ -1013,6 +1016,17 @@ pub enum MacStmtStyle { NoBraces, } +/// A `let .. && let && .. else { .. }` declaration. +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct LetElse { + pub attrs: AttrVec, + pub expr: P, + pub id: NodeId, + pub r#else: P, + pub span: Span, + pub tokens: Option, +} + /// Local represents a `let` statement, e.g., `let : = ;`. #[derive(Clone, Encodable, Decodable, Debug)] pub struct Local { @@ -1033,24 +1047,13 @@ pub enum LocalKind { /// Local declaration with an initializer. /// Example: `let x = y;` Init(P), - /// Local declaration with an initializer and an `else` clause. - /// Example: `let Some(x) = y else { return };` - InitElse(P, P), } impl LocalKind { pub fn init(&self) -> Option<&Expr> { match self { Self::Decl => None, - Self::Init(i) | Self::InitElse(i, _) => Some(i), - } - } - - pub fn init_else_opt(&self) -> Option<(&Expr, Option<&Block>)> { - match self { - Self::Decl => None, - Self::Init(init) => Some((init, None)), - Self::InitElse(init, els) => Some((init, Some(els))), + Self::Init(i) => Some(i), } } } diff --git a/compiler/rustc_ast/src/ast_like.rs b/compiler/rustc_ast/src/ast_like.rs index 9a24158ba35d9..f8811d3ae8308 100644 --- a/compiler/rustc_ast/src/ast_like.rs +++ b/compiler/rustc_ast/src/ast_like.rs @@ -2,7 +2,7 @@ use super::ptr::P; use super::token::Nonterminal; use super::tokenstream::LazyTokenStream; use super::{Arm, Crate, ExprField, FieldDef, GenericParam, Param, PatField, Variant}; -use super::{AssocItem, Expr, ForeignItem, Item, Local, MacCallStmt}; +use super::{AssocItem, Expr, ForeignItem, Item, LetElse, Local, MacCallStmt}; use super::{AttrItem, AttrKind, Block, Pat, Path, Ty, Visibility}; use super::{AttrVec, Attribute, Stmt, StmtKind}; @@ -104,6 +104,7 @@ impl AstLike for StmtKind { fn attrs(&self) -> &[Attribute] { match self { + StmtKind::LetElse(let_else) => let_else.attrs(), StmtKind::Local(local) => local.attrs(), StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.attrs(), StmtKind::Item(item) => item.attrs(), @@ -114,6 +115,7 @@ impl AstLike for StmtKind { fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { match self { + StmtKind::LetElse(let_else) => let_else.visit_attrs(f), StmtKind::Local(local) => local.visit_attrs(f), StmtKind::Expr(expr) | StmtKind::Semi(expr) => expr.visit_attrs(f), StmtKind::Item(item) => item.visit_attrs(f), @@ -123,6 +125,7 @@ impl AstLike for StmtKind { } fn tokens_mut(&mut self) -> Option<&mut Option> { Some(match self { + StmtKind::LetElse(let_else) => &mut let_else.tokens, StmtKind::Local(local) => &mut local.tokens, StmtKind::Item(item) => &mut item.tokens, StmtKind::Expr(expr) | StmtKind::Semi(expr) => &mut expr.tokens, @@ -271,7 +274,7 @@ derive_has_tokens_and_attrs! { derive_has_tokens_and_attrs! { const SUPPORTS_CUSTOM_INNER_ATTRS: bool = false; - Local, MacCallStmt, Expr + LetElse, Local, MacCallStmt, Expr } // These ast nodes only support inert attributes, so they don't diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index a81a227629539..d71a1c5f0f90f 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -201,6 +201,10 @@ pub trait MutVisitor: Sized { noop_visit_parenthesized_parameter_data(p, self); } + fn visit_let_else(&mut self, let_else: &mut P) { + noop_visit_let_else(let_else, self); + } + fn visit_local(&mut self, l: &mut P) { noop_visit_local(l, self); } @@ -569,6 +573,16 @@ pub fn noop_visit_parenthesized_parameter_data( vis.visit_span(span); } +pub fn noop_visit_let_else(let_else: &mut P, vis: &mut T) { + let LetElse { attrs, expr, id, r#else, span, tokens } = let_else.deref_mut(); + visit_thin_attrs(attrs, vis); + vis.visit_expr(expr); + vis.visit_id(id); + vis.visit_block(r#else); + vis.visit_span(span); + visit_lazy_tts(tokens, vis); +} + pub fn noop_visit_local(local: &mut P, vis: &mut T) { let Local { id, pat, ty, kind, span, attrs, tokens } = local.deref_mut(); vis.visit_id(id); @@ -579,10 +593,6 @@ pub fn noop_visit_local(local: &mut P, vis: &mut T) { LocalKind::Init(init) => { vis.visit_expr(init); } - LocalKind::InitElse(init, els) => { - vis.visit_expr(init); - vis.visit_block(els); - } } vis.visit_span(span); visit_thin_attrs(attrs, vis); @@ -1408,6 +1418,10 @@ pub fn noop_flat_map_stmt_kind( vis: &mut T, ) -> SmallVec<[StmtKind; 1]> { match kind { + StmtKind::LetElse(mut let_else) => smallvec![StmtKind::LetElse({ + vis.visit_let_else(&mut let_else); + let_else + })], StmtKind::Local(mut local) => smallvec![StmtKind::Local({ vis.visit_local(&mut local); local diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 73e9297549cd4..a97f4dc663f5a 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -93,6 +93,9 @@ pub trait Visitor<'ast>: Sized { fn visit_item(&mut self, i: &'ast Item) { walk_item(self, i) } + fn visit_let_else(&mut self, let_else: &'ast LetElse) { + walk_let_else(self, let_else) + } fn visit_local(&mut self, l: &'ast Local) { walk_local(self, l) } @@ -239,16 +242,20 @@ pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) { walk_list!(visitor, visit_attribute, &krate.attrs); } +pub fn walk_let_else<'a, V: Visitor<'a>>(visitor: &mut V, let_else: &'a LetElse) { + for attr in let_else.attrs.iter() { + visitor.visit_attribute(attr); + } + visitor.visit_expr(&let_else.expr); + visitor.visit_block(&let_else.r#else); +} + pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) { for attr in local.attrs.iter() { visitor.visit_attribute(attr); } visitor.visit_pat(&local.pat); walk_list!(visitor, visit_ty, &local.ty); - if let Some((init, els)) = local.kind.init_else_opt() { - visitor.visit_expr(init); - walk_list!(visitor, visit_block, els); - } } pub fn walk_label<'a, V: Visitor<'a>>(visitor: &mut V, label: &'a Label) { @@ -695,6 +702,7 @@ pub fn walk_block<'a, V: Visitor<'a>>(visitor: &mut V, block: &'a Block) { pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) { match statement.kind { + StmtKind::LetElse(ref let_else) => visitor.visit_let_else(let_else), StmtKind::Local(ref local) => visitor.visit_local(local), StmtKind::Item(ref item) => visitor.visit_item(item), StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr), diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index 082c5bb783347..5ad5523871e85 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -1,5 +1,5 @@ use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext}; -use rustc_ast::{AttrVec, Block, BlockCheckMode, Expr, Local, LocalKind, Stmt, StmtKind}; +use rustc_ast::{AttrVec, Block, BlockCheckMode, LetElse, Local, Stmt, StmtKind}; use rustc_hir as hir; use rustc_session::parse::feature_err; use rustc_span::{sym, DesugaringKind}; @@ -34,23 +34,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let mut expr = None; while let [s, tail @ ..] = ast_stmts { match s.kind { + StmtKind::LetElse(ref let_else) => { + expr = Some(self.lower_let_else(let_else, tail)); + // remaining statements are in let-else expression + break; + } StmtKind::Local(ref local) => { let hir_id = self.lower_node_id(s.id); - match &local.kind { - LocalKind::InitElse(init, els) => { - let e = self.lower_let_else(hir_id, local, init, els, tail); - expr = Some(e); - // remaining statements are in let-else expression - break; - } - _ => { - let local = self.lower_local(local); - self.alias_attrs(hir_id, local.hir_id); - let kind = hir::StmtKind::Local(local); - let span = self.lower_span(s.span); - stmts.push(hir::Stmt { hir_id, kind, span }); - } - } + let local = self.lower_local(local); + self.alias_attrs(hir_id, local.hir_id); + let kind = hir::StmtKind::Local(local); + let span = self.lower_span(s.span); + stmts.push(hir::Stmt { hir_id, kind, span }); } StmtKind::Item(ref it) => { stmts.extend(self.lower_item_ref(it).into_iter().enumerate().map( @@ -116,54 +111,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_let_else( - &mut self, - stmt_hir_id: hir::HirId, - local: &Local, - init: &Expr, - els: &Block, - tail: &[Stmt], - ) -> &'hir hir::Expr<'hir> { - let ty = local - .ty - .as_ref() - .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding))); - let span = self.lower_span(local.span); - let span = self.mark_span_with_reason(DesugaringKind::LetElse, span, None); - let init = self.lower_expr(init); - let local_hir_id = self.lower_node_id(local.id); - self.lower_attrs(local_hir_id, &local.attrs); - let let_expr = { - let lex = self.arena.alloc(hir::Let { - hir_id: local_hir_id, - pat: self.lower_pat(&local.pat), - ty, - init, - span, - }); - self.arena.alloc(self.expr(span, hir::ExprKind::Let(lex), AttrVec::new())) - }; + fn lower_let_else(&mut self, let_else: &LetElse, tail: &[Stmt]) -> &'hir hir::Expr<'hir> { + let span = self.mark_span_with_reason(DesugaringKind::LetElse, let_else.span, None); + let local_hir_id = self.lower_node_id(let_else.id); + self.lower_attrs(local_hir_id, &let_else.attrs); + let cond = self.lower_expr(&let_else.expr); let then_expr = { let (stmts, expr) = self.lower_stmts(tail); let block = self.block_all(span, stmts, expr); self.arena.alloc(self.expr_block(block, AttrVec::new())) }; let else_expr = { - let block = self.lower_block(els, false); + let block = self.lower_block(&let_else.r#else, false); self.arena.alloc(self.expr_block(block, AttrVec::new())) }; - self.alias_attrs(let_expr.hir_id, local_hir_id); + self.alias_attrs(cond.hir_id, local_hir_id); self.alias_attrs(else_expr.hir_id, local_hir_id); let if_expr = self.arena.alloc(hir::Expr { - hir_id: stmt_hir_id, + hir_id: local_hir_id, span, - kind: hir::ExprKind::If(let_expr, then_expr, Some(else_expr)), + kind: hir::ExprKind::If(cond, then_expr, Some(else_expr)), }); if !self.sess.features_untracked().let_else { feature_err( &self.sess.parse_sess, sym::let_else, - local.span, + let_else.span, "`let...else` statements are unstable", ) .emit(); diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 96dbd3dca156e..2a93cf877ef1d 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1073,26 +1073,27 @@ impl<'a> State<'a> { crate fn print_stmt(&mut self, st: &ast::Stmt) { self.maybe_print_comment(st.span.lo()); match st.kind { + ast::StmtKind::LetElse(ref let_else) => { + self.print_outer_attributes(&let_else.attrs); + self.space_if_not_bol(); + self.ibox(INDENT_UNIT); + self.word_nbsp("let"); + self.print_expr(&let_else.expr); + self.cbox(INDENT_UNIT); + self.ibox(INDENT_UNIT); + self.word(" else "); + self.print_block(&let_else.r#else); + self.word(";"); + self.end(); // `let` ibox + } ast::StmtKind::Local(ref loc) => { self.print_outer_attributes(&loc.attrs); self.space_if_not_bol(); self.ibox(INDENT_UNIT); self.word_nbsp("let"); - self.ibox(INDENT_UNIT); self.print_local_decl(loc); self.end(); - if let Some((init, els)) = loc.kind.init_else_opt() { - self.nbsp(); - self.word_space("="); - self.print_expr(init); - if let Some(els) = els { - self.cbox(INDENT_UNIT); - self.ibox(INDENT_UNIT); - self.word(" else "); - self.print_block(els); - } - } self.word(";"); self.end(); // `let` ibox } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 9a4daa6d7500a..b09dd53ebceb4 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1364,7 +1364,7 @@ impl InvocationCollectorNode for ast::Stmt { StmtKind::Item(item) => matches!(item.kind, ItemKind::MacCall(..)), StmtKind::Semi(expr) => matches!(expr.kind, ExprKind::MacCall(..)), StmtKind::Expr(..) => unreachable!(), - StmtKind::Local(..) | StmtKind::Empty => false, + StmtKind::LetElse(..) | StmtKind::Local(..) | StmtKind::Empty => false, } } fn take_mac_call(self) -> (ast::MacCall, Self::AttrsTy, AddSemicolon) { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 24d295ee9fbf6..90cdd5c54e982 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1054,7 +1054,7 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: & impl EarlyLintPass for UnusedDocComment { fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &ast::Stmt) { let kind = match stmt.kind { - ast::StmtKind::Local(..) => "statements", + ast::StmtKind::LetElse(..) | ast::StmtKind::Local(..) => "statements", // Disabled pending discussion in #78306 ast::StmtKind::Item(..) => return, // expressions will be reported by `check_expr`. diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 755e24d541398..76b1f8e66f799 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -623,11 +623,8 @@ trait UnusedDelimLint { fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) { match s.kind { StmtKind::Local(ref local) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => { - if let Some((init, els)) = local.kind.init_else_opt() { - let ctx = match els { - None => UnusedDelimsCtx::AssignedValue, - Some(_) => UnusedDelimsCtx::AssignedValueLetElse, - }; + if let Some(init) = local.kind.init() { + let ctx = UnusedDelimsCtx::AssignedValue; self.check_unused_delims_expr(cx, init, ctx, false, None, None); } } diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index d3e7d1690ccf6..a11bbf988daa1 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -16,7 +16,7 @@ use rustc_ast::util::classify; use rustc_ast::{ AstLike, AttrStyle, AttrVec, Attribute, LocalKind, MacCall, MacCallStmt, MacStmtStyle, }; -use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt}; +use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, LetElse, Local, Stmt}; use rustc_ast::{StmtKind, DUMMY_NODE_ID}; use rustc_errors::{Applicability, DiagnosticBuilder, PResult}; use rustc_span::source_map::{BytePos, Span}; @@ -60,7 +60,11 @@ impl<'a> Parser<'a> { } Ok(Some(if self.token.is_keyword(kw::Let) { - self.parse_local_mk(lo, attrs, capture_semi, force_collect)? + if self.eat_keyword(kw::Else) { + self.parse_let_else_mk(lo, attrs, capture_semi, force_collect)? + } else { + self.parse_local_mk(lo, attrs, capture_semi, force_collect)? + } } else if self.is_kw_followed_by_ident(kw::Mut) { self.recover_stmt_local(lo, attrs, "missing keyword", "let mut")? } else if self.is_kw_followed_by_ident(kw::Auto) { @@ -204,6 +208,42 @@ impl<'a> Parser<'a> { Ok(stmt) } + /// Parses a local variable declaration. + fn parse_let_else(&mut self, attrs: AttrVec) -> PResult<'a, P> { + if self.token.is_keyword(kw::If) { + // `let...else if`. Emit the same error that `parse_block()` would, + // but explicitly point out that this pattern is not allowed. + let msg = "conditional `else if` is not supported for `let...else`"; + return Err(self.error_block_no_opening_brace_msg(msg)); + } + let lo = self.prev_token.span; + let expr = self.parse_expr()?; + let r#else = self.parse_block()?; + self.check_let_else_init_bool_expr(&expr); + self.check_let_else_init_trailing_brace(&expr); + let hi = if self.token == token::Semi { self.token.span } else { self.prev_token.span }; + Ok(P(LetElse { attrs, expr, id: DUMMY_NODE_ID, r#else, span: lo.to(hi), tokens: None })) + } + + fn parse_let_else_mk( + &mut self, + lo: Span, + attrs: AttrWrapper, + capture_semi: bool, + force_collect: ForceCollect, + ) -> PResult<'a, Stmt> { + self.collect_tokens_trailing_token(attrs, force_collect, |this, attrs| { + this.expect_keyword(kw::Let)?; + let let_else = this.parse_let_else(attrs.into())?; + let trailing = if capture_semi && this.token.kind == token::Semi { + TrailingToken::Semi + } else { + TrailingToken::None + }; + Ok((this.mk_stmt(lo.to(this.prev_token.span), StmtKind::LetElse(let_else)), trailing)) + }) + } + fn parse_local_mk( &mut self, lo: Span, @@ -304,22 +344,7 @@ impl<'a> Parser<'a> { }; let kind = match init { None => LocalKind::Decl, - Some(init) => { - if self.eat_keyword(kw::Else) { - if self.token.is_keyword(kw::If) { - // `let...else if`. Emit the same error that `parse_block()` would, - // but explicitly point out that this pattern is not allowed. - let msg = "conditional `else if` is not supported for `let...else`"; - return Err(self.error_block_no_opening_brace_msg(msg)); - } - let els = self.parse_block()?; - self.check_let_else_init_bool_expr(&init); - self.check_let_else_init_trailing_brace(&init); - LocalKind::InitElse(init, els) - } else { - LocalKind::Init(init) - } - } + Some(init) => LocalKind::Init(init), }; let hi = if self.token == token::Semi { self.token.span } else { self.prev_token.span }; Ok(P(ast::Local { ty, pat, kind, id: DUMMY_NODE_ID, span: lo.to(hi), attrs, tokens: None })) @@ -327,6 +352,9 @@ impl<'a> Parser<'a> { fn check_let_else_init_bool_expr(&self, init: &ast::Expr) { if let ast::ExprKind::Binary(op, ..) = init.kind { + if let ast::BinOpKind::And = op.node { + return; + } if op.node.lazy() { let suggs = vec![ (init.span.shrink_to_lo(), "(".to_string()), @@ -574,7 +602,7 @@ impl<'a> Parser<'a> { StmtKind::Local(ref mut local) if let Err(e) = self.expect_semi() => { // We might be at the `,` in `let x = foo;`. Try to recover. match &mut local.kind { - LocalKind::Init(expr) | LocalKind::InitElse(expr, _) => { + LocalKind::Init(expr) => { self.check_mistyped_turbofish_with_multiple_type_params(e, expr)?; // We found `foo`, have we fully recovered? self.expect_semi()?; @@ -583,7 +611,7 @@ impl<'a> Parser<'a> { } eat_semi = false; } - StmtKind::Empty | StmtKind::Item(_) | StmtKind::Local(_) | StmtKind::Semi(_) => eat_semi = false, + StmtKind::Empty | StmtKind::Item(_) | StmtKind::LetElse(_) | StmtKind::Local(_) | StmtKind::Semi(_) => eat_semi = false, } if eat_semi && self.eat(&token::Semi) { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2c678e71ae179..58f198a95cb58 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1500,13 +1500,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { walk_list!(self, visit_ty, &local.ty); // Resolve the initializer. - if let Some((init, els)) = local.kind.init_else_opt() { + if let Some(init) = local.kind.init() { self.visit_expr(init); - - // Resolve the `else` block - if let Some(els) = els { - self.visit_block(els); - } } // Resolve the pattern. diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs index 0d0c88b02c78b..79c7d723b0d7d 100644 --- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs +++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs @@ -319,11 +319,8 @@ impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> { impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> { fn visit_local(&mut self, local: &'tcx Local) { - if let Some((init, els)) = &local.kind.init_else_opt() { + if let Some(init) = &local.kind.init() { self.apply(|this| walk_expr(this, init)); - if let Some(els) = els { - self.apply(|this| walk_block(this, els)); - } } // add the pattern after the expression because the bindings aren't available // yet in the init diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 3f4043ad052a0..2b9625cbddb8e 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -232,8 +232,6 @@ pub fn eq_local_kind(l: &LocalKind, r: &LocalKind) -> bool { use LocalKind::*; match (l, r) { (Decl, Decl) => true, - (Init(l), Init(r)) => eq_expr(l, r), - (InitElse(li, le), InitElse(ri, re)) => eq_expr(li, ri) && eq_block(le, re), _ => false, } } diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs index 3887a8051f209..4d4f396ba390b 100644 --- a/src/tools/rustfmt/src/attr.rs +++ b/src/tools/rustfmt/src/attr.rs @@ -40,6 +40,7 @@ pub(crate) fn get_attrs_from_stmt(stmt: &ast::Stmt) -> &[ast::Attribute] { pub(crate) fn get_span_without_attrs(stmt: &ast::Stmt) -> Span { match stmt.kind { + ast::StmtKind::LetElse(ref let_else) => let_else.span, ast::StmtKind::Local(ref local) => local.span, ast::StmtKind::Item(ref item) => item.span, ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => expr.span, diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index babc56f86edc6..9e8719a7b9fea 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -54,7 +54,7 @@ impl Rewrite for ast::Local { skip_out_of_file_lines_range!(context, self.span); - if contains_skip(&self.attrs) || matches!(self.kind, ast::LocalKind::InitElse(..)) { + if contains_skip(&self.attrs) { return None; } @@ -112,7 +112,7 @@ impl Rewrite for ast::Local { result.push_str(&infix); - if let Some((init, _els)) = self.kind.init_else_opt() { + if let Some(init) = self.kind.init() { // 1 = trailing semicolon; let nested_shape = shape.sub_width(1)?; diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs index 8e6c75a3744ac..14eb5dd5b93c9 100644 --- a/src/tools/rustfmt/src/spanned.rs +++ b/src/tools/rustfmt/src/spanned.rs @@ -61,6 +61,7 @@ implement_spanned!(ast::Local); impl Spanned for ast::Stmt { fn span(&self) -> Span { match self.kind { + ast::StmtKind::LetElse(_) => { todo!() } ast::StmtKind::Local(ref local) => mk_sp(local.span().lo(), self.span.hi()), ast::StmtKind::Item(ref item) => mk_sp(item.span().lo(), self.span.hi()), ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => { diff --git a/src/tools/rustfmt/src/stmt.rs b/src/tools/rustfmt/src/stmt.rs index 0b3854425ea5f..39f6553d715d7 100644 --- a/src/tools/rustfmt/src/stmt.rs +++ b/src/tools/rustfmt/src/stmt.rs @@ -99,6 +99,7 @@ fn format_stmt( skip_out_of_file_lines_range!(context, stmt.span()); let result = match stmt.kind { + ast::StmtKind::LetElse(_) => { todo!() }, ast::StmtKind::Local(ref local) => local.rewrite(context, shape), ast::StmtKind::Expr(ref ex) | ast::StmtKind::Semi(ref ex) => { let suffix = if semicolon_for_stmt(context, stmt) { diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index 0177689958aa7..730d6a5d31bb2 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs @@ -153,7 +153,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.visit_item(item); self.last_pos = stmt.span().hi(); } - ast::StmtKind::Local(..) | ast::StmtKind::Expr(..) | ast::StmtKind::Semi(..) => { + ast::StmtKind::LetElse(..) | ast::StmtKind::Local(..) | ast::StmtKind::Expr(..) | ast::StmtKind::Semi(..) => { let attrs = get_attrs_from_stmt(stmt.as_ast_node()); if contains_skip(attrs) { self.push_skipped_with_span(