Skip to content

Commit 8e4c9e4

Browse files
committed
Fixed interior mutable references causing a mark
The mutability system now checks where derefs go through borrows in the loan chain, and can correctly detect mutable borrows inside structs and tuples.
1 parent 400075d commit 8e4c9e4

File tree

1 file changed

+31
-24
lines changed
  • src/librustc_borrowck/borrowck/gather_loans

1 file changed

+31
-24
lines changed

src/librustc_borrowck/borrowck/gather_loans/mod.rs

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -431,38 +431,45 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
431431
// }
432432
// }
433433
}
434-
434+
435435
pub fn mark_loan_path_as_mutated(&self, loan_path: &LoanPath) {
436436
//! For mutable loans of content whose mutability derives
437437
//! from a local variable, mark the mutability decl as necessary.
438438
439-
match loan_path.kind {
440-
LpVar(local_id) |
441-
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
442-
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
443-
}
444-
LpExtend(ref base, mc::McInherited, LpDeref(pointer_kind)) |
445-
LpExtend(ref base, mc::McDeclared, LpDeref(pointer_kind)) => {
446-
match base.kind {
447-
LpVar(_) if pointer_kind != mc::Unique => {
448-
// If you mutate the inside of a ref var, the var itself
449-
// is not used mutably [Issue #25049]
450-
// Unless it's a Box! (mc::Unique)
439+
let mut wrapped_path = Some(loan_path);
440+
let mut through_borrow = false;
441+
442+
while let Some(current_path) = wrapped_path {
443+
wrapped_path = match current_path.kind {
444+
LpVar(local_id) => {
445+
if !through_borrow {
446+
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
451447
}
452-
_ => {
453-
self.mark_loan_path_as_mutated(&base);
448+
None
449+
}
450+
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
451+
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
452+
None
453+
}
454+
LpExtend(ref base, mc::McInherited, LpDeref(pointer_kind)) |
455+
LpExtend(ref base, mc::McDeclared, LpDeref(pointer_kind)) => {
456+
if pointer_kind != mc::Unique {
457+
through_borrow = true;
454458
}
459+
Some(base)
455460
}
456-
}
457-
LpDowncast(ref base, _) |
458-
LpExtend(ref base, mc::McInherited, _) |
459-
LpExtend(ref base, mc::McDeclared, _) => {
460-
self.mark_loan_path_as_mutated(&base);
461-
}
462-
LpExtend(_, mc::McImmutable, _) => {
463-
// Nothing to do.
464-
}
461+
LpDowncast(ref base, _) |
462+
LpExtend(ref base, mc::McInherited, _) |
463+
LpExtend(ref base, mc::McDeclared, _) => {
464+
Some(base)
465+
}
466+
LpExtend(_, mc::McImmutable, _) => {
467+
// Nothing to do.
468+
None
469+
}
470+
}
465471
}
472+
466473
}
467474

468475
pub fn compute_gen_scope(&self,

0 commit comments

Comments
 (0)