diff options
author | Sergey Pepyakin <s.pepyakin@gmail.com> | 2017-10-05 13:06:55 +0300 |
---|---|---|
committer | Sergey Pepyakin <s.pepyakin@gmail.com> | 2017-10-05 20:43:15 +0300 |
commit | e14a49ac812483e36072799cfbf2a0959500f600 (patch) | |
tree | 68a37ab45f9122d2f7662378edc986682ef74f2f | |
parent | a1c6802bee7b687ae64e90acc4dc8d4b03ffe3ab (diff) |
Introduce `with_loaned_item`.
-rw-r--r-- | src/ir/context.rs | 65 |
1 files changed, 39 insertions, 26 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs index 706531ef..61dce891 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -965,6 +965,29 @@ impl BindgenContext { } } + /// Temporarily loan `Item` with the given `ItemId`. This provides means to + /// mutably borrow `Item` while having a reference to `BindgenContext`. + /// + /// `Item` with the given `ItemId` is removed from the context, given + /// closure is executed and then `Item` is placed back. + /// + /// # Panics + /// + /// Panics if attempt to resolve given `ItemId` inside the given + /// closure is made. + fn with_loaned_item<F: FnOnce(&BindgenContext, &mut Item)>( + &mut self, + item_id: ItemId, + f: F, + ) { + let mut item = self.items.remove(&item_id).unwrap(); + + f(self, &mut item); + + let existing = self.items.insert(item_id, item); + assert!(existing.is_none()); + } + /// Compute the bitfield allocation units for all `TypeKind::Comp` items we /// parsed. fn compute_bitfield_units(&mut self) { @@ -973,22 +996,14 @@ impl BindgenContext { let need_bitfield_allocation = mem::replace(&mut self.need_bitfield_allocation, vec![]); for id in need_bitfield_allocation { - // To appease the borrow checker, we temporarily remove this item - // from the context, and then replace it once we are done computing - // its bitfield units. We will never try and resolve this - // `TypeKind::Comp` item's id (which would now cause a panic) during - // bitfield unit computation because it is a non-scalar by - // definition, and non-scalar types may not be used as bitfields. - let mut item = self.items.remove(&id).unwrap(); - - item.kind_mut() - .as_type_mut() - .unwrap() - .as_comp_mut() - .unwrap() - .compute_bitfield_units(&*self); - - self.items.insert(id, item); + self.with_loaned_item(id, |ctx, item| { + item.kind_mut() + .as_type_mut() + .unwrap() + .as_comp_mut() + .unwrap() + .compute_bitfield_units(ctx); + }); } } @@ -1010,16 +1025,14 @@ impl BindgenContext { .collect(); for id in comp_item_ids { - let mut item = self.items.remove(&id).unwrap(); - - item.kind_mut() - .as_type_mut() - .unwrap() - .as_comp_mut() - .unwrap() - .deanonymize_fields(self); - - self.items.insert(id, item); + self.with_loaned_item(id, |ctx, item| { + item.kind_mut() + .as_type_mut() + .unwrap() + .as_comp_mut() + .unwrap() + .deanonymize_fields(ctx); + }); } } |