diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2016-11-03 14:01:11 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-03 14:01:11 -0500 |
commit | be2fbb30aa797def69b061214980f36e3c2321f5 (patch) | |
tree | c23c2cc30439b3978b87fe2293188d75a0facac6 /src | |
parent | 591524ceb21f7864b67f03428185aa7f5913f92a (diff) | |
parent | eff92920d42eb87a9dedc5fb32c02aac382a51c5 (diff) |
Auto merge of #199 - fitzgen:replace-template-alias, r=emilio
Do not overwrite existing replacements
It turns out that we can end up overwriting existing replacements. This commit embeds the assumption that the first replacement definition is the correct one, and warns on all attempts to overwrite the first replacement definition with a new one. Additionally, it adds some debug logging about replacements.
This actually isn't enough to fix the test case in #89, but it is a good start.
r? @emilio
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/context.rs | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs index c2214340..c1dba549 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -4,7 +4,7 @@ use BindgenOptions; use clang::{self, Cursor}; use parse::ClangItemParser; use std::borrow::{Borrow, Cow}; -use std::collections::{HashMap, HashSet}; +use std::collections::{HashMap, HashSet, hash_map}; use std::collections::btree_map::{self, BTreeMap}; use std::fmt; use super::int::IntKind; @@ -308,6 +308,7 @@ impl<'ctx> BindgenContext<'ctx> { /// `replaces="SomeType"` annotation with the replacement type. fn process_replacements(&mut self) { if self.replacements.is_empty() { + debug!("No replacements to process"); return; } @@ -347,6 +348,8 @@ impl<'ctx> BindgenContext<'ctx> { } for (id, replacement) in replacements { + debug!("Replacing {:?} with {:?}", id, replacement); + let mut item = self.items.get_mut(&id).unwrap(); *item.kind_mut().as_type_mut().unwrap().kind_mut() = TypeKind::ResolvedTypeRef(replacement); @@ -725,7 +728,21 @@ impl<'ctx> BindgenContext<'ctx> { /// Replacement types are declared using the `replaces="xxx"` annotation, /// and implies that the original type is hidden. pub fn replace(&mut self, name: &str, potential_ty: ItemId) { - self.replacements.insert(name.into(), potential_ty); + match self.replacements.entry(name.into()) { + hash_map::Entry::Vacant(entry) => { + debug!("Defining replacement for {} as {:?}", + name, + potential_ty); + entry.insert(potential_ty); + } + hash_map::Entry::Occupied(occupied) => { + warn!("Replacement for {} already defined as {:?}; \ + ignoring duplicate replacement definition as {:?}}}", + name, + occupied.get(), + potential_ty); + } + } } /// Is the item with the given `name` hidden? Or is the item with the given |