]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/check/method/confirm.rs
rustc_typeck: do not overlap a borrow of TypeckTables with method lookup.
[rust.git] / src / librustc_typeck / check / method / confirm.rs
index c8815f3df5aa25ecda4a4772b287a9b1eec84c21..36bd665738951ff3c29a47871b72be393771ea83 100644 (file)
@@ -446,9 +446,13 @@ fn convert_lvalue_derefs_to_mutable(&self) {
             // overloaded lvalue ops, and will be fixed by them in order to get
             // the correct region.
             let mut source = self.node_ty(expr.id);
-            if let Some(adjustments) = self.tables.borrow_mut().adjustments.get_mut(&expr.id) {
+            // Do not mutate adjustments in place, but rather take them,
+            // and replace them after mutating them, to avoid having the
+            // tables borrowed during (`deref_mut`) method resolution.
+            let previous_adjustments = self.tables.borrow_mut().adjustments.remove(&expr.id);
+            if let Some(mut adjustments) = previous_adjustments {
                 let pref = LvaluePreference::PreferMutLvalue;
-                for adjustment in adjustments {
+                for adjustment in &mut adjustments {
                     if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind {
                         if let Some(ok) = self.try_overloaded_deref(expr.span, source, pref) {
                             let method = self.register_infer_ok_obligations(ok);
@@ -462,6 +466,7 @@ fn convert_lvalue_derefs_to_mutable(&self) {
                     }
                     source = adjustment.target;
                 }
+                self.tables.borrow_mut().adjustments.insert(expr.id, adjustments);
             }
 
             match expr.node {