Skip to content

Commit a886b08

Browse files
authored
Unrolled build for rust-lang#141267
Rollup merge of rust-lang#141267 - dianne:fix-141265, r=oli-obk only resolve top-level guard patterns' guards once We resolve guard patterns' guards in `resolve_pattern_inner`, so to avoid resolving them multiple times, we must avoid doing so earlier. To accomplish this, `LateResolutionVisitor::visit_pat` contains a case for guard patterns that avoids visiting their guards while walking patterns. This PR fixes rust-lang#141265, which was due to `visit::walk_pat` being used instead; this meant guards at the top level of a pattern would be visited twice. e.g. it would ICE on `for x if x in [] {}`, but not `for (x if x) in [] {}`. `visit_pat` was already used for the guard pattern in the second example, on account of the top-level pattern being parens.
2 parents 356f2d0 + ed983c2 commit a886b08

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

compiler/rustc_resolve/src/late.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3901,7 +3901,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
39013901
// We walk the pattern before declaring the pattern's inner bindings,
39023902
// so that we avoid resolving a literal expression to a binding defined
39033903
// by the pattern.
3904-
visit::walk_pat(self, pat);
3904+
// NB: `Self::visit_pat` must be used rather than `visit::walk_pat` to avoid resolving guard
3905+
// patterns' guard expressions multiple times (#141265).
3906+
self.visit_pat(pat);
39053907
self.resolve_pattern_inner(pat, pat_src, bindings);
39063908
// This has to happen *after* we determine which pat_idents are variants:
39073909
self.check_consistent_bindings(pat);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//! Regression test for <https://github.com/rust-lang/rust/issues/141265>.
2+
//! Make sure expressions in top-level guard patterns are only resolved once.
3+
4+
fn main() {
5+
for
6+
else if b 0 {}
7+
//~^ ERROR expected identifier, found keyword `else`
8+
//~| ERROR missing `in` in `for` loop
9+
//~| ERROR cannot find value `b` in this scope
10+
//~| ERROR guard patterns are experimental
11+
//~| ERROR `{integer}` is not an iterator
12+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
error: expected identifier, found keyword `else`
2+
--> $DIR/only-resolve-top-level-guard-expr-once-ice-141265.rs:6:5
3+
|
4+
LL | else if b 0 {}
5+
| ^^^^ expected identifier, found keyword
6+
7+
error: missing `in` in `for` loop
8+
--> $DIR/only-resolve-top-level-guard-expr-once-ice-141265.rs:6:14
9+
|
10+
LL | else if b 0 {}
11+
| ^
12+
|
13+
help: try adding `in` here
14+
|
15+
LL | else if b in 0 {}
16+
| ++
17+
18+
error[E0425]: cannot find value `b` in this scope
19+
--> $DIR/only-resolve-top-level-guard-expr-once-ice-141265.rs:6:13
20+
|
21+
LL | else if b 0 {}
22+
| ^ not found in this scope
23+
24+
error[E0658]: guard patterns are experimental
25+
--> $DIR/only-resolve-top-level-guard-expr-once-ice-141265.rs:6:13
26+
|
27+
LL | else if b 0 {}
28+
| ^
29+
|
30+
= note: see issue #129967 <https://github.com/rust-lang/rust/issues/129967> for more information
31+
= help: add `#![feature(guard_patterns)]` to the crate attributes to enable
32+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
33+
= help: consider using match arm guards
34+
35+
error[E0277]: `{integer}` is not an iterator
36+
--> $DIR/only-resolve-top-level-guard-expr-once-ice-141265.rs:6:15
37+
|
38+
LL | else if b 0 {}
39+
| ^ `{integer}` is not an iterator
40+
|
41+
= help: the trait `Iterator` is not implemented for `{integer}`
42+
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
43+
= note: required for `{integer}` to implement `IntoIterator`
44+
45+
error: aborting due to 5 previous errors
46+
47+
Some errors have detailed explanations: E0277, E0425, E0658.
48+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)