Skip to content

Commit 4a8ba7b

Browse files
dedicated visitor for arm patterns
1 parent df127b8 commit 4a8ba7b

File tree

1 file changed

+41
-18
lines changed

1 file changed

+41
-18
lines changed

compiler/rustc_typeck/src/check/generator_interior.rs

+41-18
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ struct InteriorVisitor<'a, 'tcx> {
2828
/// such borrows can span across this yield point.
2929
/// As such, we need to track these borrows and record them despite of the fact
3030
/// that they may succeed the said yield point in the post-order.
31-
nested_scope_of_guards: SmallVec<[SmallVec<[HirId; 4]>; 4]>,
32-
current_scope_of_guards: HirIdSet,
33-
arm_has_guard: bool,
31+
guard_bindings: SmallVec<[SmallVec<[HirId; 4]>; 1]>,
32+
guard_bindings_set: HirIdSet,
3433
}
3534

3635
impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
@@ -147,9 +146,8 @@ pub fn resolve_interior<'a, 'tcx>(
147146
expr_count: 0,
148147
kind,
149148
prev_unresolved_span: None,
150-
nested_scope_of_guards: <_>::default(),
151-
current_scope_of_guards: <_>::default(),
152-
arm_has_guard: false,
149+
guard_bindings: <_>::default(),
150+
guard_bindings_set: <_>::default(),
153151
};
154152
intravisit::walk_body(&mut visitor, body);
155153

@@ -228,25 +226,34 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
228226

229227
fn visit_arm(&mut self, arm: &'tcx Arm<'tcx>) {
230228
if arm.guard.is_some() {
231-
self.nested_scope_of_guards.push(<_>::default());
232-
self.arm_has_guard = true;
229+
self.guard_bindings.push(<_>::default());
233230
}
234231
self.visit_pat(&arm.pat);
235232
if let Some(ref g) = arm.guard {
233+
self.guard_bindings.push(<_>::default());
234+
ArmPatCollector {
235+
guard_bindings_set: &mut self.guard_bindings_set,
236+
guard_bindings: self
237+
.guard_bindings
238+
.last_mut()
239+
.expect("should have pushed at least one earlier"),
240+
}
241+
.visit_pat(&arm.pat);
242+
236243
match g {
237244
Guard::If(ref e) => {
238245
self.visit_expr(e);
239246
}
240247
}
248+
241249
let mut scope_var_ids =
242-
self.nested_scope_of_guards.pop().expect("should have pushed at least one earlier");
250+
self.guard_bindings.pop().expect("should have pushed at least one earlier");
243251
for var_id in scope_var_ids.drain(..) {
244252
assert!(
245-
self.current_scope_of_guards.remove(&var_id),
253+
self.guard_bindings_set.remove(&var_id),
246254
"variable should be placed in scope earlier"
247255
);
248256
}
249-
self.arm_has_guard = false;
250257
}
251258
self.visit_expr(&arm.body);
252259
}
@@ -256,14 +263,10 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
256263

257264
self.expr_count += 1;
258265

259-
if let PatKind::Binding(_, id, ..) = pat.kind {
266+
if let PatKind::Binding(..) = pat.kind {
260267
let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id);
261268
let ty = self.fcx.typeck_results.borrow().pat_ty(pat);
262269
self.record(ty, Some(scope), None, pat.span, false);
263-
if self.arm_has_guard {
264-
self.nested_scope_of_guards.as_mut_slice().last_mut().unwrap().push(id);
265-
self.current_scope_of_guards.insert(id);
266-
}
267270
}
268271
}
269272

@@ -299,8 +302,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
299302
intravisit::walk_expr(self, expr);
300303
let res = self.fcx.typeck_results.borrow().qpath_res(qpath, expr.hir_id);
301304
match res {
302-
Res::Local(id) if self.current_scope_of_guards.contains(&id) => {
303-
debug!("a borrow in guard from pattern local is detected");
305+
Res::Local(id) if self.guard_bindings_set.contains(&id) => {
304306
guard_borrowing_from_pattern = true;
305307
}
306308
_ => {}
@@ -350,3 +352,24 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
350352
}
351353
}
352354
}
355+
356+
struct ArmPatCollector<'a> {
357+
guard_bindings_set: &'a mut HirIdSet,
358+
guard_bindings: &'a mut SmallVec<[HirId; 4]>,
359+
}
360+
361+
impl<'a, 'tcx> Visitor<'tcx> for ArmPatCollector<'a> {
362+
type Map = intravisit::ErasedMap<'tcx>;
363+
364+
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
365+
NestedVisitorMap::None
366+
}
367+
368+
fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
369+
intravisit::walk_pat(self, pat);
370+
if let PatKind::Binding(_, id, ..) = pat.kind {
371+
self.guard_bindings.push(id);
372+
self.guard_bindings_set.insert(id);
373+
}
374+
}
375+
}

0 commit comments

Comments
 (0)