summary refs log tree commit diff
path: root/compiler/rustc_resolve
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-06-02 02:14:32 +0000
committerMichael Goulet <michael@errs.io>2025-06-02 02:19:34 +0000
commitd2d0f62f783b0640f7ededb25776a724031cebf7 (patch)
tree686b26a4ad9e8b56eb22c17f31ae7f04400638a3 /compiler/rustc_resolve
parentec28ae9454139023117270985f114823d6570657 (diff)
downloadrust-d2d0f62f783b0640f7ededb25776a724031cebf7.tar.gz
rust-d2d0f62f783b0640f7ededb25776a724031cebf7.zip
Don't declare variables in ExprKind::Let in invalid positions
Diffstat (limited to 'compiler/rustc_resolve')
-rw-r--r--compiler/rustc_resolve/src/late.rs19
1 files changed, 18 insertions, 1 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index fb1534d0b27..aaec376e687 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -4891,11 +4891,28 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 self.resolve_expr(e, Some(expr));
             }
 
-            ExprKind::Let(ref pat, ref scrutinee, _, _) => {
+            ExprKind::Let(ref pat, ref scrutinee, _, Recovered::No) => {
                 self.visit_expr(scrutinee);
                 self.resolve_pattern_top(pat, PatternSource::Let);
             }
 
+            ExprKind::Let(ref pat, ref scrutinee, _, Recovered::Yes(_)) => {
+                self.visit_expr(scrutinee);
+                // This is basically a tweaked, inlined `resolve_pattern_top`.
+                let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
+                self.resolve_pattern(pat, PatternSource::Let, &mut bindings);
+                // We still collect the bindings in this `let` expression which is in
+                // an invalid position (and therefore shouldn't declare variables into
+                // its parent scope). To avoid unnecessary errors though, we do just
+                // reassign the resolutions to `Res::Err`.
+                for (_, bindings) in &mut bindings {
+                    for (_, binding) in bindings {
+                        *binding = Res::Err;
+                    }
+                }
+                self.apply_pattern_bindings(bindings);
+            }
+
             ExprKind::If(ref cond, ref then, ref opt_else) => {
                 self.with_rib(ValueNS, RibKind::Normal, |this| {
                     let old = this.diag_metadata.in_if_condition.replace(cond);