-
Notifications
You must be signed in to change notification settings - Fork 13.3k
gather_locals
: only visit guard pattern guards when checking the guard
#141275
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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 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".
r? @nnethercote rustbot has assigned @nnethercote. Use |
@@ -218,7 +218,12 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { | |||
); | |||
} | |||
let old_outermost_fn_param_pat = self.outermost_fn_param_pat.take(); | |||
intravisit::walk_pat(self, p); | |||
if let PatKind::Guard(subpat, _) = p.kind { | |||
// We'll visit the guard when checking it. Don't gather its locals twice. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I don't understand this. When is the guard expression checked, if not here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's checked in check_pat_inner
; see the check_expr_has_type_or_error
call there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense. Since I introduced the regression, I'm happy to approve it. It's kinda a shame we have to special case guards here, but it makes sense, since this is the only case where we have a nested expr within a pattern.
We could alternatively do something like override visit_expr
to be a noop, but whatever, this current approach keeps the behavior more localized.
@@ -218,7 +218,12 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> { | |||
); | |||
} | |||
let old_outermost_fn_param_pat = self.outermost_fn_param_pat.take(); | |||
intravisit::walk_pat(self, p); | |||
if let PatKind::Guard(subpat, _) = p.kind { | |||
// We'll visit the guard when checking it. Don't gather its locals twice. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's checked in check_pat_inner
; see the check_expr_has_type_or_error
call there.
r? compiler-errors @bors r+ rollup |
…iaskrgr Rollup of 7 pull requests Successful merges: - rust-lang#139419 (Error on recursive opaque ty in HIR typeck) - rust-lang#141236 (Resolved issue with mismatched types triggering ICE in certain scenarios) - rust-lang#141253 (Warning added when dependency crate has async drop types, and the feature is disabled) - rust-lang#141269 (rustc-dev-guide subtree update) - rust-lang#141275 (`gather_locals`: only visit guard pattern guards when checking the guard) - rust-lang#141279 (`lower_to_hir` cleanups) - rust-lang#141285 (Add tick to `RePlaceholder` debug output) r? `@ghost` `@rustbot` modify labels: rollup
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
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: #129967