From 5e53d929e4638976cac6b9a3069860af8fe814fc Mon Sep 17 00:00:00 2001 From: byd1 <2156864690@qq.com> Date: Sun, 28 Jun 2026 14:19:13 +0800 Subject: [PATCH] fix --- compiler/rustc_parse/src/parser/stmt.rs | 20 +++++++++++++++++-- .../ui/let-else/detect-invisible-delimiter.rs | 16 +++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 tests/ui/let-else/detect-invisible-delimiter.rs diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 5bd2ca3139228..2b63a31a139da 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -5,6 +5,7 @@ use std::ops::Bound; use ast::Label; use rustc_ast as ast; use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind}; +use rustc_ast::tokenstream::TokenTree; use rustc_ast::util::classify::{self, TrailingBrace}; use rustc_ast::visit::{Visitor, walk_expr}; use rustc_ast::{ @@ -353,6 +354,14 @@ impl<'a> Parser<'a> { } else { (None, None, None) }; + + let init_wrapped = self + .tree_look_ahead(2, |tree| match tree { + TokenTree::Token(tok, _) => tok.is_keyword(kw::Else), + TokenTree::Delimited(..) => false, + }) + .unwrap_or(false); + let init = match (self.parse_initializer(err.is_some()), err) { (Ok(init), None) => { // init parsed, ty parsed @@ -390,6 +399,7 @@ impl<'a> Parser<'a> { return Err(err); } }; + let trailing_token = self.prev_token; let kind = match init { None => LocalKind::Decl, Some(init) => { @@ -401,8 +411,14 @@ impl<'a> Parser<'a> { return Err(self.error_block_no_opening_brace_msg(Cow::from(msg))); } let els = self.parse_block()?; - self.check_let_else_init_bool_expr(&init); - self.check_let_else_init_trailing_brace(&init); + // These checks should also respect invisible delimiter + if !init_wrapped { + self.check_let_else_init_bool_expr(&init); + } + if matches!(trailing_token.kind, TokenKind::CloseBrace) { + self.check_let_else_init_trailing_brace(&init); + } + LocalKind::InitElse(init, els) } else { LocalKind::Init(init) diff --git a/tests/ui/let-else/detect-invisible-delimiter.rs b/tests/ui/let-else/detect-invisible-delimiter.rs new file mode 100644 index 0000000000000..76c231bd21e6d --- /dev/null +++ b/tests/ui/let-else/detect-invisible-delimiter.rs @@ -0,0 +1,16 @@ +// The user shouldn't need to wrap the expression in parentheses(#147899) +//@check-pass +#![allow(irrefutable_let_patterns)] +struct Thing {} +macro_rules! foo { + ($e:expr) => { + let _ = $e else { + return; + }; + }; +} + +fn main() { + foo!(true && true); + foo!(Thing {}); +}