Skip to content

Commit a29bdb1

Browse files
authored
Unrolled build for rust-lang#141275
Rollup merge of rust-lang#141275 - dianne:gather-guard-pat-locals-once, r=compiler-errors `gather_locals`: only visit guard pattern guards when checking the guard When checking a pattern with guards in it, `GatherLocalsVisitor` will visit both the pattern (when type-checking the let, arm, or param containing it) and local declarations in the guard expression (when checking the guard itself). This keeps it from visiting the guard when visiting the pattern, since otherwise it would gather locals from the guard twice, which would lead to a delayed bug: "evaluated expression more than once". Tracking issue for guard patterns: rust-lang#129967
2 parents 6cab15c + c343b2a commit a29bdb1

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

compiler/rustc_hir_typeck/src/gather_locals.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,12 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
218218
);
219219
}
220220
let old_outermost_fn_param_pat = self.outermost_fn_param_pat.take();
221-
intravisit::walk_pat(self, p);
221+
if let PatKind::Guard(subpat, _) = p.kind {
222+
// We'll visit the guard when checking it. Don't gather its locals twice.
223+
self.visit_pat(subpat);
224+
} else {
225+
intravisit::walk_pat(self, p);
226+
}
222227
self.outermost_fn_param_pat = old_outermost_fn_param_pat;
223228
}
224229

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ check-pass
2+
//! Test that `GatherLocalsVisitor` only visits expressions in guard patterns when checking the
3+
//! expressions, and not a second time when visiting the pattern. If locals are declared inside the
4+
//! the guard expression, it would ICE if visited twice ("evaluated expression more than once").
5+
6+
#![feature(guard_patterns)]
7+
#![expect(incomplete_features)]
8+
9+
fn main() {
10+
match (0,) {
11+
// FIXME(guard_patterns): liveness lints don't work yet; this will ICE without the `_`.
12+
(_ if { let _x = false; _x },) => {}
13+
_ => {}
14+
}
15+
}

0 commit comments

Comments
 (0)