diff options
author | Nick Fitzgerald <fitzgen@gmail.com> | 2016-11-03 13:01:41 -0700 |
---|---|---|
committer | Nick Fitzgerald <fitzgen@gmail.com> | 2016-11-03 14:18:06 -0700 |
commit | 8041ebfdbcf11fc327b6b4bfd56a243a16fc80d7 (patch) | |
tree | c0fabf1c80c5d45fbcfd3ec396e175bb0f67728e | |
parent | eff92920d42eb87a9dedc5fb32c02aac382a51c5 (diff) |
Allow template aliases to be considered for replacement
-rw-r--r-- | src/ir/context.rs | 24 | ||||
-rw-r--r-- | src/ir/item.rs | 10 | ||||
-rw-r--r-- | tests/expectations/replace_template_alias.rs | 15 | ||||
-rw-r--r-- | tests/headers/replace_template_alias.hpp | 23 |
4 files changed, 57 insertions, 15 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs index b51a2cb9..9ffb1b7a 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -320,23 +320,27 @@ impl<'ctx> BindgenContext<'ctx> { let mut replacements = vec![]; for (id, item) in self.items.iter() { + // Calls to `canonical_name` are expensive, so eagerly filter out + // items that cannot be replaced. let ty = match item.kind().as_type() { Some(ty) => ty, None => continue, }; - // canonical_name calls are expensive. - let ci = match ty.as_comp() { - Some(ci) => ci, - None => continue, - }; - - if ci.is_template_specialization() { - continue; + match *ty.kind() { + TypeKind::Comp(ref ci) if !ci.is_template_specialization() => {} + TypeKind::TemplateAlias(_, _) | + TypeKind::Alias(_, _) => {} + _ => continue, } - if let Some(replacement) = self.replacements - .get(&item.canonical_name(self)) { + let name = item.real_canonical_name(self, + self.options() + .enable_cxx_namespaces, + true); + let replacement = self.replacements.get(&name); + + if let Some(replacement) = replacement { if replacement != id { // We set this just after parsing the annotation. It's // very unlikely, but this can happen. diff --git a/src/ir/item.rs b/src/ir/item.rs index 690f4222..d986bb32 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -539,11 +539,11 @@ impl Item { /// /// This name should be derived from the immutable state contained in the /// type and the parent chain, since it should be consistent. - fn real_canonical_name(&self, - ctx: &BindgenContext, - count_namespaces: bool, - for_name_checking: bool) - -> String { + pub fn real_canonical_name(&self, + ctx: &BindgenContext, + count_namespaces: bool, + for_name_checking: bool) + -> String { let base_name = match *self.kind() { ItemKind::Type(ref ty) => { match *ty.kind() { diff --git a/tests/expectations/replace_template_alias.rs b/tests/expectations/replace_template_alias.rs new file mode 100644 index 00000000..61a2fbcc --- /dev/null +++ b/tests/expectations/replace_template_alias.rs @@ -0,0 +1,15 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct Rooted<T> { + pub ptr: MaybeWrapped<T>, +} +/// But the replacement type does use T! +/// +/// <div rustbindgen replaces="MaybeWrapped" /> +pub type MaybeWrapped<T> = T; diff --git a/tests/headers/replace_template_alias.hpp b/tests/headers/replace_template_alias.hpp new file mode 100644 index 00000000..6ceae4e5 --- /dev/null +++ b/tests/headers/replace_template_alias.hpp @@ -0,0 +1,23 @@ +// bindgen-flags: -- --std=c++14 + +namespace JS { +namespace detail { + +/// Notice how this doesn't use T. +template <typename T> +using MaybeWrapped = int; + +} + +template <typename T> +class Rooted { + detail::MaybeWrapped<T> ptr; +}; + +} + +/// But the replacement type does use T! +/// +/// <div rustbindgen replaces="MaybeWrapped" /> +template <typename T> +using replaces_MaybeWrapped = T; |