From 2a93916e32692ecf6581138353bfa29671e342f9 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 15:36:49 -0700 Subject: [PATCH 01/25] Introduce the `TypeId` newtype over `ItemId` This commit also makes `BindgenContext::resolve_type` take a `TypeId`, and adds unchecked conversions everywhere that we call it. Next, I'm going to go through the code base, replacing these unchecked conversions with checked ones, and tightening up types as I go. --- src/codegen/impl_debug.rs | 2 +- src/codegen/mod.rs | 14 +++--- src/codegen/struct_layout.rs | 2 +- src/ir/analysis/derive_debug.rs | 2 +- src/ir/analysis/derive_hash.rs | 2 +- .../derive_partial_eq_or_partial_ord.rs | 2 +- src/ir/analysis/has_type_param_in_array.rs | 2 +- src/ir/analysis/template_params.rs | 4 +- src/ir/comp.rs | 8 ++-- src/ir/context.rs | 47 +++++++++++++++---- src/ir/enum_ty.rs | 2 +- src/ir/ty.rs | 16 +++---- src/ir/var.rs | 2 +- 13 files changed, 68 insertions(+), 37 deletions(-) diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs index 7ef108da5c..e111ecc6f1 100644 --- a/src/codegen/impl_debug.rs +++ b/src/codegen/impl_debug.rs @@ -203,7 +203,7 @@ impl<'a> ImplDebug<'a> for Item { } TypeKind::Pointer(inner) => { - let inner_type = ctx.resolve_type(inner).canonical_type(ctx); + let inner_type = ctx.resolve_type(inner.as_type_id_unchecked()).canonical_type(ctx); match *inner_type.kind() { TypeKind::Function(ref sig) if !sig.can_trivially_derive_debug() => { diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 895422b09f..5910229649 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -689,7 +689,7 @@ impl CodeGenerator for Type { let params: Vec<_> = params.into_iter() .filter_map(|p| p.as_template_param(ctx, &())) .collect(); - if params.iter().any(|p| ctx.resolve_type(*p).is_invalid_type_param()) { + if params.iter().any(|p| ctx.resolve_type(p.as_type_id_unchecked()).is_invalid_type_param()) { warn!( "Item contained invalid template \ parameter: {:?}", @@ -1112,7 +1112,7 @@ impl Bitfield { ctor_impl: quote::Tokens, unit_field_int_ty: "e::Tokens, ) -> quote::Tokens { - let bitfield_ty = ctx.resolve_type(self.ty()); + let bitfield_ty = ctx.resolve_type(self.ty().as_type_id_unchecked()); let bitfield_ty_layout = bitfield_ty.layout(ctx).expect( "Bitfield without layout? Gah!", ); @@ -1542,7 +1542,7 @@ impl CodeGenerator for CompInfo { continue; } - let base_ty = ctx.resolve_type(base.ty); + let base_ty = ctx.resolve_type(base.ty.as_type_id_unchecked()); // NB: We won't include unsized types in our base chain because they // would contribute to our size given the dummy field we insert for // unsized types. @@ -1673,7 +1673,7 @@ impl CodeGenerator for CompInfo { let mut param_names = vec![]; for (idx, ty) in params.iter().enumerate() { - let param = ctx.resolve_type(*ty); + let param = ctx.resolve_type(ty.as_type_id_unchecked()); let name = param.name().unwrap(); let ident = ctx.rust_ident(name); param_names.push(ident.clone()); @@ -2318,7 +2318,7 @@ impl CodeGenerator for Enum { let enum_ty = item.expect_type(); let layout = enum_ty.layout(ctx); - let repr = self.repr().map(|repr| ctx.resolve_type(repr)); + let repr = self.repr().map(|repr| ctx.resolve_type(repr.as_type_id_unchecked())); let repr = match repr { Some(repr) => { match *repr.canonical_type(ctx).kind() { @@ -2932,7 +2932,7 @@ impl TryToRustTy for Type { } TypeKind::Pointer(inner) | TypeKind::Reference(inner) => { - let is_const = self.is_const() || ctx.resolve_type(inner).is_const(); + let is_const = self.is_const() || ctx.resolve_type(inner.as_type_id_unchecked()).is_const(); let inner = inner.into_resolver().through_type_refs().resolve(ctx); let inner_ty = inner.expect_type(); @@ -3641,7 +3641,7 @@ mod utils { let arg_ty = match *arg_ty.canonical_type(ctx).kind() { TypeKind::Array(t, _) => { t.to_rust_ty_or_opaque(ctx, &()) - .to_ptr(ctx.resolve_type(t).is_const()) + .to_ptr(ctx.resolve_type(t.as_type_id_unchecked()).is_const()) }, TypeKind::Pointer(inner) => { let inner = ctx.resolve_item(inner); diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index 06059853b0..9e08b13ff3 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -166,7 +166,7 @@ impl<'a> StructLayoutTracker<'a> { // // This means that the structs in the array are super-unsafe to // access, since they won't be properly aligned, but *shrug*. - if let Some(layout) = self.ctx.resolve_type(inner).layout( + if let Some(layout) = self.ctx.resolve_type(inner.as_type_id_unchecked()).layout( self.ctx, ) { diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs index 7df745c9de..fd9fe2ccd3 100644 --- a/src/ir/analysis/derive_debug.rs +++ b/src/ir/analysis/derive_debug.rs @@ -294,7 +294,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { TypeKind::Pointer(inner) => { let inner_type = - self.ctx.resolve_type(inner).canonical_type(self.ctx); + self.ctx.resolve_type(inner.as_type_id_unchecked()).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { if !sig.can_trivially_derive_debug() { trace!( diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index 5313cae3c2..f53dbfc7a5 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -197,7 +197,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { TypeKind::Pointer(inner) => { let inner_type = - self.ctx.resolve_type(inner).canonical_type(self.ctx); + self.ctx.resolve_type(inner.as_type_id_unchecked()).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { if !sig.can_trivially_derive_hash() { trace!( diff --git a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs index f34a256a84..0e01247ec7 100644 --- a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs +++ b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs @@ -209,7 +209,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { TypeKind::Pointer(inner) => { let inner_type = - self.ctx.resolve_type(inner).canonical_type(self.ctx); + self.ctx.resolve_type(inner.as_type_id_unchecked()).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { if !sig.can_trivially_derive_partialeq_or_partialord() { trace!( diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs index f21bae14e2..5b034cca25 100644 --- a/src/ir/analysis/has_type_param_in_array.rs +++ b/src/ir/analysis/has_type_param_in_array.rs @@ -147,7 +147,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { TypeKind::Array(t, _) => { let inner_ty = - self.ctx.resolve_type(t).canonical_type(self.ctx); + self.ctx.resolve_type(t.as_type_id_unchecked()).canonical_type(self.ctx); match *inner_ty.kind() { TypeKind::TypeParam => { trace!(" Array with Named type has type parameter"); diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs index 7699a0c239..ea4bd7b8a9 100644 --- a/src/ir/analysis/template_params.rs +++ b/src/ir/analysis/template_params.rs @@ -271,7 +271,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> { ) { trace!(" template instantiation"); - let decl = self.ctx.resolve_type(instantiation.template_definition()); + let decl = self.ctx.resolve_type(instantiation.template_definition().as_type_id_unchecked()); let args = instantiation.template_arguments(); let params = decl.self_template_params(self.ctx).unwrap_or(vec![]); @@ -411,7 +411,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // generic template parameters are used. ctx.resolve_item(item).as_type().map(|ty| match ty.kind() { &TypeKind::TemplateInstantiation(ref inst) => { - let decl = ctx.resolve_type(inst.template_definition()); + let decl = ctx.resolve_type(inst.template_definition().as_type_id_unchecked()); let args = inst.template_arguments(); // Although template definitions should always have diff --git a/src/ir/comp.rs b/src/ir/comp.rs index e1b2a1f00b..1bc53d1d8c 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -176,7 +176,7 @@ impl Field { layout, .. }) => Some(layout), Field::DataMember(ref data) => { - ctx.resolve_type(data.ty).layout(ctx) + ctx.resolve_type(data.ty.as_type_id_unchecked()).layout(ctx) } } } @@ -538,7 +538,7 @@ fn bitfields_to_allocation_units( for bitfield in raw_bitfields { let bitfield_width = bitfield.bitfield().unwrap() as usize; - let bitfield_layout = ctx.resolve_type(bitfield.ty()) + let bitfield_layout = ctx.resolve_type(bitfield.ty().as_type_id_unchecked()) .layout(ctx) .expect("Bitfield without layout? Gah!"); let bitfield_size = bitfield_layout.size; @@ -913,7 +913,7 @@ impl CompInfo { pub fn is_unsized(&self, ctx: &BindgenContext, itemid: &ItemId) -> bool { !ctx.lookup_item_id_has_vtable(itemid) && self.fields().is_empty() && self.base_members.iter().all(|base| { - ctx.resolve_type(base.ty).canonical_type(ctx).is_unsized( + ctx.resolve_type(base.ty.as_type_id_unchecked()).canonical_type(ctx).is_unsized( ctx, &base.ty, ) @@ -1362,7 +1362,7 @@ impl CompInfo { // Unfortunately, given the way we implement --match-pat, and also // that you can inherit from templated types, we need to handle // other cases here too. - ctx.resolve_type(base.ty) + ctx.resolve_type(base.ty.as_type_id_unchecked()) .canonical_type(ctx) .as_comp() .map_or(false, |_| ctx.lookup_item_id_has_vtable(&base.ty)) diff --git a/src/ir/context.rs b/src/ir/context.rs index 5b6b46efd0..f864ed8424 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -32,15 +32,46 @@ use std::iter::IntoIterator; use std::mem; /// A single identifier for an item. -/// -/// TODO: Build stronger abstractions on top of this, like TypeId(ItemId)? #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ItemId(usize); +/// An identifier for an `Item` whose `ItemKind` is known to be +/// `ItemKind::Type`. +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct TypeId(ItemId); + +impl From for ItemId { + fn from(tid: TypeId) -> ItemId { + tid.0 + } +} + +impl From for usize { + fn from(id: ItemId) -> usize { + id.0 + } +} + impl ItemId { /// Get a numeric representation of this id. pub fn as_usize(&self) -> usize { - self.0 + (*self).into() + } + + /// Convert this `ItemId` into a `TypeId` if its associated item is a type, + /// otherwise return `None`. + pub fn as_type_id(&self, ctx: &BindgenContext) -> Option { + if ctx.resolve_item(*self).kind().is_type() { + Some(self.as_type_id_unchecked()) + } else { + None + } + } + + /// Convert this `ItemId` into a `TypeId` without actually checking whether + /// this id actually points to a `Type`. + pub fn as_type_id_unchecked(&self) -> TypeId { + TypeId(*self) } } @@ -1212,16 +1243,16 @@ impl BindgenContext { /// /// Panics if there is no item for the given `ItemId` or if the resolved /// item is not a `Type`. - pub fn resolve_type(&self, type_id: ItemId) -> &Type { - self.items.get(&type_id).unwrap().kind().expect_type() + pub fn resolve_type(&self, type_id: TypeId) -> &Type { + self.items.get(&type_id.into()).unwrap().kind().expect_type() } /// Resolve the given `ItemId` as a type, or `None` if there is no item with /// the given id. /// /// Panics if the id resolves to an item that is not a type. - pub fn safe_resolve_type(&self, type_id: ItemId) -> Option<&Type> { - self.items.get(&type_id).map(|t| t.kind().expect_type()) + pub fn safe_resolve_type(&self, type_id: TypeId) -> Option<&Type> { + self.items.get(&type_id.into()).map(|t| t.kind().expect_type()) } /// Resolve the given `ItemId` into an `Item`, or `None` if no such item @@ -1371,7 +1402,7 @@ impl BindgenContext { ) -> Option { use clang_sys; - let num_expected_args = match self.resolve_type(template) + let num_expected_args = match self.resolve_type(template.as_type_id_unchecked()) .num_self_template_params(self) { Some(n) => n, None => { diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index dc56f64aa5..c02f01636e 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -72,7 +72,7 @@ impl Enum { // Assume signedness since the default type by the C standard is an int. let is_signed = repr.and_then( - |r| ctx.resolve_type(r).safe_canonical_type(ctx), + |r| ctx.resolve_type(r.as_type_id_unchecked()).safe_canonical_type(ctx), ).map_or(true, |ty| match *ty.kind() { TypeKind::Int(ref int_kind) => int_kind.is_signed(), ref other => { diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 8cfbde10e2..301f543d8c 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -215,7 +215,7 @@ impl Type { if len == 0 { Some(item) } else { None } } TypeKind::ResolvedTypeRef(inner) => { - ctx.resolve_type(inner).is_incomplete_array(ctx) + ctx.resolve_type(inner.as_type_id_unchecked()).is_incomplete_array(ctx) } _ => None, } @@ -238,7 +238,7 @@ impl Type { )) } TypeKind::ResolvedTypeRef(inner) => { - ctx.resolve_type(inner).layout(ctx) + ctx.resolve_type(inner.as_type_id_unchecked()).layout(ctx) } _ => None, } @@ -333,10 +333,10 @@ impl Type { TypeKind::ResolvedTypeRef(inner) | TypeKind::Alias(inner) | TypeKind::TemplateAlias(inner, _) => { - ctx.resolve_type(inner).safe_canonical_type(ctx) + ctx.resolve_type(inner.as_type_id_unchecked()).safe_canonical_type(ctx) } TypeKind::TemplateInstantiation(ref inst) => { - ctx.resolve_type(inst.template_definition()) + ctx.resolve_type(inst.template_definition().as_type_id_unchecked()) .safe_canonical_type(ctx) } @@ -546,7 +546,7 @@ impl TemplateParameters for TypeKind { ) -> Option> { match *self { TypeKind::ResolvedTypeRef(id) => { - ctx.resolve_type(id).self_template_params(ctx) + ctx.resolve_type(id.as_type_id_unchecked()).self_template_params(ctx) } TypeKind::Comp(ref comp) => comp.self_template_params(ctx), TypeKind::TemplateAlias(_, ref args) => Some(args.clone()), @@ -701,16 +701,16 @@ impl Type { TypeKind::Comp(ref ci) => ci.is_unsized(ctx, itemid), TypeKind::Opaque => self.layout.map_or(true, |l| l.size == 0), TypeKind::Array(inner, size) => { - size == 0 || ctx.resolve_type(inner).is_unsized(ctx, &inner) + size == 0 || ctx.resolve_type(inner.as_type_id_unchecked()).is_unsized(ctx, &inner) } TypeKind::ResolvedTypeRef(inner) | TypeKind::Alias(inner) | TypeKind::TemplateAlias(inner, _) => { - ctx.resolve_type(inner).is_unsized(ctx, &inner) + ctx.resolve_type(inner.as_type_id_unchecked()).is_unsized(ctx, &inner) } TypeKind::TemplateInstantiation(ref inst) => { let definition = inst.template_definition(); - ctx.resolve_type(definition).is_unsized(ctx, &definition) + ctx.resolve_type(definition.as_type_id_unchecked()).is_unsized(ctx, &definition) } TypeKind::TypeParam | TypeKind::Int(..) | diff --git a/src/ir/var.rs b/src/ir/var.rs index 987bfd5048..5fafd72d4c 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -236,7 +236,7 @@ impl ClangSubItemParser for Var { // tests/headers/inner_const.hpp // // That's fine because in that case we know it's not a literal. - let canonical_ty = ctx.safe_resolve_type(ty).and_then(|t| { + let canonical_ty = ctx.safe_resolve_type(ty.as_type_id_unchecked()).and_then(|t| { t.safe_canonical_type(ctx) }); From f5b06edf555f931bdf343cff3beb42edd9c63ba0 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 15:44:28 -0700 Subject: [PATCH 02/25] Remove unused parameter to `codegen::utils::type_from_named` --- src/codegen/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 5910229649..d3a8dd40b1 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -599,7 +599,7 @@ impl CodeGenerator for Type { // If this is a known named type, disallow generating anything // for it too. let spelling = self.name().expect("Unnamed alias?"); - if utils::type_from_named(ctx, spelling, inner).is_some() { + if utils::type_from_named(ctx, spelling).is_some() { return; } @@ -2889,8 +2889,8 @@ impl TryToRustTy for Type { inst.try_to_rust_ty(ctx, item) } TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()), - TypeKind::TemplateAlias(inner, _) | - TypeKind::Alias(inner) => { + TypeKind::TemplateAlias(..) | + TypeKind::Alias(..) => { let template_params = item.used_template_params(ctx) .unwrap_or(vec![]) .into_iter() @@ -2903,7 +2903,6 @@ impl TryToRustTy for Type { } else if let Some(ty) = utils::type_from_named( ctx, spelling, - inner, ) { Ok(ty) @@ -3583,7 +3582,6 @@ mod utils { pub fn type_from_named( ctx: &BindgenContext, name: &str, - _inner: ItemId, ) -> Option { // FIXME: We could use the inner item to check this is really a // primitive type but, who the heck overrides these anyway? From dd68ec864a00b34b614a348a91f9c5a258ca81bc Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 15:46:44 -0700 Subject: [PATCH 03/25] Turn `build_templated_path` into `build_path` None of the callers were passing template parameters. --- src/codegen/mod.rs | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index d3a8dd40b1..8a20094803 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2907,7 +2907,7 @@ impl TryToRustTy for Type { { Ok(ty) } else { - utils::build_templated_path(item, ctx, vec![]) //template_params) + utils::build_path(item, ctx) } } TypeKind::Comp(ref info) => { @@ -2918,8 +2918,7 @@ impl TryToRustTy for Type { return self.try_to_opaque(ctx, item); } - // let template_params = template_params.unwrap_or(vec![]); - utils::build_templated_path(item, ctx, vec![]) + utils::build_path(item, ctx) } TypeKind::Opaque => self.try_to_opaque(ctx, item), TypeKind::BlockPointer => { @@ -3325,8 +3324,8 @@ pub fn codegen(context: &mut BindgenContext) -> Vec { } mod utils { - use super::{ToRustTyOrOpaque, TryToRustTy, error}; - use ir::context::{BindgenContext, ItemId}; + use super::{ToRustTyOrOpaque, error}; + use ir::context::BindgenContext; use ir::function::FunctionSig; use ir::item::{Item, ItemCanonicalPath}; use ir::ty::TypeKind; @@ -3548,28 +3547,16 @@ mod utils { result.extend(old_items.into_iter()); } - pub fn build_templated_path( + pub fn build_path( item: &Item, ctx: &BindgenContext, - template_params: Vec, ) -> error::Result { let path = item.namespace_aware_canonical_path(ctx); - let template_params = template_params - .iter() - .map(|param| param.try_to_rust_ty(ctx, &())) - .collect::>>()?; - let mut tokens = quote! {}; tokens.append_separated(path.into_iter().map(quote::Ident::new), "::"); - if template_params.is_empty() { - Ok(tokens) - } else { - Ok(quote! { - #tokens < #( #template_params ),* > - }) - } + Ok(tokens) } fn primitive_ty(ctx: &BindgenContext, name: &str) -> quote::Tokens { From bd232fb54061d81b1219805d4905d8835a0d84f0 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 15:55:16 -0700 Subject: [PATCH 04/25] Resolve an `Item` with any id type that converts into an `ItemId` --- src/ir/context.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ir/context.rs b/src/ir/context.rs index f864ed8424..8f36a0b8ef 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1264,7 +1264,8 @@ impl BindgenContext { /// Resolve the given `ItemId` into an `Item`. /// /// Panics if the given id does not resolve to any item. - pub fn resolve_item(&self, item_id: ItemId) -> &Item { + pub fn resolve_item>(&self, item_id: Id) -> &Item { + let item_id = item_id.into(); match self.items.get(&item_id) { Some(item) => item, None => panic!("Not an item: {:?}", item_id), From bd324232ef905a2186cf88510a68c27d55859a30 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 16:09:52 -0700 Subject: [PATCH 05/25] Make `TypeKind::{Alias,TemplateAlias,Array,Pointer,Reference}` use `TypeId` This commit makes certain `TypeKind`s that can only reference other types use `TypeId` instead of `ItemId`. --- src/codegen/impl_debug.rs | 2 +- src/codegen/mod.rs | 18 ++++--- src/codegen/struct_layout.rs | 2 +- src/ir/analysis/derive_copy.rs | 4 +- src/ir/analysis/derive_debug.rs | 6 +-- src/ir/analysis/derive_default.rs | 4 +- src/ir/analysis/derive_hash.rs | 6 +-- .../derive_partial_eq_or_partial_ord.rs | 6 +-- src/ir/analysis/has_destructor.rs | 2 +- src/ir/analysis/has_float.rs | 4 +- src/ir/analysis/has_type_param_in_array.rs | 4 +- src/ir/analysis/has_vtable.rs | 2 +- src/ir/context.rs | 24 ++++++--- src/ir/function.rs | 4 +- src/ir/item.rs | 13 +++-- src/ir/ty.rs | 52 +++++++++---------- src/ir/var.rs | 2 +- 17 files changed, 89 insertions(+), 66 deletions(-) diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs index e111ecc6f1..7ef108da5c 100644 --- a/src/codegen/impl_debug.rs +++ b/src/codegen/impl_debug.rs @@ -203,7 +203,7 @@ impl<'a> ImplDebug<'a> for Item { } TypeKind::Pointer(inner) => { - let inner_type = ctx.resolve_type(inner.as_type_id_unchecked()).canonical_type(ctx); + let inner_type = ctx.resolve_type(inner).canonical_type(ctx); match *inner_type.kind() { TypeKind::Function(ref sig) if !sig.can_trivially_derive_debug() => { diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 8a20094803..b0c1b18e27 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2728,7 +2728,10 @@ where } } -impl TryToOpaque for ItemId { +impl TryToOpaque for T +where + T: Copy + Into +{ type Extra = (); fn try_get_layout( @@ -2736,11 +2739,14 @@ impl TryToOpaque for ItemId { ctx: &BindgenContext, _: &(), ) -> error::Result { - ctx.resolve_item(*self).try_get_layout(ctx, &()) + ctx.resolve_item((*self).into()).try_get_layout(ctx, &()) } } -impl TryToRustTy for ItemId { +impl TryToRustTy for T +where + T: Copy + Into +{ type Extra = (); fn try_to_rust_ty( @@ -2748,7 +2754,7 @@ impl TryToRustTy for ItemId { ctx: &BindgenContext, _: &(), ) -> error::Result { - ctx.resolve_item(*self).try_to_rust_ty(ctx, &()) + ctx.resolve_item((*self).into()).try_to_rust_ty(ctx, &()) } } @@ -2930,7 +2936,7 @@ impl TryToRustTy for Type { } TypeKind::Pointer(inner) | TypeKind::Reference(inner) => { - let is_const = self.is_const() || ctx.resolve_type(inner.as_type_id_unchecked()).is_const(); + let is_const = self.is_const() || ctx.resolve_type(inner).is_const(); let inner = inner.into_resolver().through_type_refs().resolve(ctx); let inner_ty = inner.expect_type(); @@ -3626,7 +3632,7 @@ mod utils { let arg_ty = match *arg_ty.canonical_type(ctx).kind() { TypeKind::Array(t, _) => { t.to_rust_ty_or_opaque(ctx, &()) - .to_ptr(ctx.resolve_type(t.as_type_id_unchecked()).is_const()) + .to_ptr(ctx.resolve_type(t).is_const()) }, TypeKind::Pointer(inner) => { let inner = ctx.resolve_item(inner); diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index 9e08b13ff3..06059853b0 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -166,7 +166,7 @@ impl<'a> StructLayoutTracker<'a> { // // This means that the structs in the array are super-unsafe to // access, since they won't be properly aligned, but *shrug*. - if let Some(layout) = self.ctx.resolve_type(inner.as_type_id_unchecked()).layout( + if let Some(layout) = self.ctx.resolve_type(inner).layout( self.ctx, ) { diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index 264d227a06..1a97f3c2d0 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -177,7 +177,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { } TypeKind::Array(t, len) => { - let cant_derive_copy = self.is_not_copy(t); + let cant_derive_copy = self.is_not_copy(t.into()); if cant_derive_copy { trace!( " arrays of T for which we cannot derive Copy \ @@ -198,7 +198,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - let cant_derive_copy = self.is_not_copy(t); + let cant_derive_copy = self.is_not_copy(t.into()); if cant_derive_copy { trace!( " arrays of T for which we cannot derive Copy \ diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs index fd9fe2ccd3..8a83613be5 100644 --- a/src/ir/analysis/derive_debug.rs +++ b/src/ir/analysis/derive_debug.rs @@ -191,7 +191,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { } TypeKind::Array(t, len) => { - if self.is_not_debug(t) { + if self.is_not_debug(t.into()) { trace!( " arrays of T for which we cannot derive Debug \ also cannot derive Debug" @@ -211,7 +211,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - if self.is_not_debug(t) { + if self.is_not_debug(t.into()) { trace!( " aliases and type refs to T which cannot derive \ Debug also cannot derive Debug" @@ -294,7 +294,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { TypeKind::Pointer(inner) => { let inner_type = - self.ctx.resolve_type(inner.as_type_id_unchecked()).canonical_type(self.ctx); + self.ctx.resolve_type(inner).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { if !sig.can_trivially_derive_debug() { trace!( diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs index 7acbe04a65..083723c77b 100644 --- a/src/ir/analysis/derive_default.rs +++ b/src/ir/analysis/derive_default.rs @@ -222,7 +222,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { } TypeKind::Array(t, len) => { - if self.is_not_default(t) { + if self.is_not_default(t.into()) { trace!( " arrays of T for which we cannot derive Default \ also cannot derive Default" @@ -242,7 +242,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - if self.is_not_default(t) { + if self.is_not_default(t.into()) { trace!( " aliases and type refs to T which cannot derive \ Default also cannot derive Default" diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index f53dbfc7a5..e2aae2f8bb 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -178,7 +178,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { } TypeKind::Array(t, len) => { - if self.cannot_derive_hash.contains(&t) { + if self.cannot_derive_hash.contains(&t.into()) { trace!( " arrays of T for which we cannot derive Hash \ also cannot derive Hash" @@ -197,7 +197,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { TypeKind::Pointer(inner) => { let inner_type = - self.ctx.resolve_type(inner.as_type_id_unchecked()).canonical_type(self.ctx); + self.ctx.resolve_type(inner).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { if !sig.can_trivially_derive_hash() { trace!( @@ -222,7 +222,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - if self.cannot_derive_hash.contains(&t) { + if self.cannot_derive_hash.contains(&t.into()) { trace!( " aliases and type refs to T which cannot derive \ Hash also cannot derive Hash" diff --git a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs index 0e01247ec7..9211bb0925 100644 --- a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs +++ b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs @@ -190,7 +190,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { } TypeKind::Array(t, len) => { - if self.cannot_derive_partialeq_or_partialord.contains(&t) { + if self.cannot_derive_partialeq_or_partialord.contains(&t.into()) { trace!( " arrays of T for which we cannot derive `PartialEq`/`PartialOrd` \ also cannot derive `PartialEq`/`PartialOrd`" @@ -209,7 +209,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { TypeKind::Pointer(inner) => { let inner_type = - self.ctx.resolve_type(inner.as_type_id_unchecked()).canonical_type(self.ctx); + self.ctx.resolve_type(inner).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { if !sig.can_trivially_derive_partialeq_or_partialord() { trace!( @@ -236,7 +236,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - if self.cannot_derive_partialeq_or_partialord.contains(&t) { + if self.cannot_derive_partialeq_or_partialord.contains(&t.into()) { trace!( " aliases and type refs to T which cannot derive \ `PartialEq`/`PartialOrd` also cannot derive `PartialEq`/`PartialOrd`" diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs index f6400d7dde..4058cd883e 100644 --- a/src/ir/analysis/has_destructor.rs +++ b/src/ir/analysis/has_destructor.rs @@ -103,7 +103,7 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> { TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) | TypeKind::ResolvedTypeRef(t) => { - if self.have_destructor.contains(&t) { + if self.have_destructor.contains(&t.into()) { self.insert(id) } else { ConstrainResult::Same diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs index 959a411b69..218572dc7a 100644 --- a/src/ir/analysis/has_float.rs +++ b/src/ir/analysis/has_float.rs @@ -140,7 +140,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { } TypeKind::Array(t, _) => { - if self.has_float.contains(&t) { + if self.has_float.contains(&t.into()) { trace!(" Array with type T that has float also has float"); return self.insert(id) } @@ -151,7 +151,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - if self.has_float.contains(&t) { + if self.has_float.contains(&t.into()) { trace!(" aliases and type refs to T which have float \ also have float"); self.insert(id) diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs index 5b034cca25..6a0e670791 100644 --- a/src/ir/analysis/has_type_param_in_array.rs +++ b/src/ir/analysis/has_type_param_in_array.rs @@ -147,7 +147,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { TypeKind::Array(t, _) => { let inner_ty = - self.ctx.resolve_type(t.as_type_id_unchecked()).canonical_type(self.ctx); + self.ctx.resolve_type(t).canonical_type(self.ctx); match *inner_ty.kind() { TypeKind::TypeParam => { trace!(" Array with Named type has type parameter"); @@ -165,7 +165,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - if self.has_type_parameter_in_array.contains(&t) { + if self.has_type_parameter_in_array.contains(&t.into()) { trace!( " aliases and type refs to T which have array \ also have array" diff --git a/src/ir/analysis/has_vtable.rs b/src/ir/analysis/has_vtable.rs index b0d487385c..53a647af1d 100644 --- a/src/ir/analysis/has_vtable.rs +++ b/src/ir/analysis/has_vtable.rs @@ -98,7 +98,7 @@ impl<'ctx> MonotoneFramework for HasVtableAnalysis<'ctx> { TypeKind::Alias(t) | TypeKind::ResolvedTypeRef(t) | TypeKind::Reference(t) => { - if self.have_vtable.contains(&t) { + if self.have_vtable.contains(&t.into()) { self.insert(id) } else { ConstrainResult::Same diff --git a/src/ir/context.rs b/src/ir/context.rs index 8f36a0b8ef..79f4012e78 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -46,6 +46,12 @@ impl From for ItemId { } } +impl<'a> From<&'a TypeId> for ItemId { + fn from(tid: &'a TypeId) -> ItemId { + tid.0 + } +} + impl From for usize { fn from(id: ItemId) -> usize { id.0 @@ -792,8 +798,7 @@ impl BindgenContext { let item = self.items.get_mut(&id).unwrap(); *item.kind_mut().as_type_mut().unwrap().kind_mut() = - TypeKind::ResolvedTypeRef(resolved); - + TypeKind::ResolvedTypeRef(resolved.as_type_id_unchecked()); resolved }; @@ -902,7 +907,7 @@ impl BindgenContext { let new_parent = { let item = self.items.get_mut(&id).unwrap(); *item.kind_mut().as_type_mut().unwrap().kind_mut() = - TypeKind::ResolvedTypeRef(replacement); + TypeKind::ResolvedTypeRef(replacement.as_type_id_unchecked()); item.parent_id() }; @@ -1701,7 +1706,7 @@ impl BindgenContext { let spelling = ty.spelling(); let is_const = ty.is_const(); let layout = ty.fallible_layout().ok(); - let type_kind = TypeKind::ResolvedTypeRef(wrapped_id); + let type_kind = TypeKind::ResolvedTypeRef(wrapped_id.as_type_id_unchecked()); let ty = Type::new(Some(spelling), layout, type_kind, is_const); let item = Item::new( with_id, @@ -2286,6 +2291,13 @@ impl ItemId { } } +impl TypeId { + pub fn into_resolver(self) -> ItemResolver { + let id: ItemId = self.into(); + id.into() + } +} + impl From for ItemResolver { fn from(id: ItemId) -> ItemResolver { ItemResolver::new(id) @@ -2325,14 +2337,14 @@ impl ItemResolver { match ty_kind { Some(&TypeKind::ResolvedTypeRef(next_id)) if self.through_type_refs => { - id = next_id; + id = next_id.into(); } // We intentionally ignore template aliases here, as they are // more complicated, and don't represent a simple renaming of // some type. Some(&TypeKind::Alias(next_id)) if self.through_type_aliases => { - id = next_id; + id = next_id.into(); } _ => return item, } diff --git a/src/ir/function.rs b/src/ir/function.rs index 402a023090..5fcd21ea4b 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -385,12 +385,12 @@ impl FunctionSig { let class = Item::parse(cursor.semantic_parent(), None, ctx) .expect("Expected to parse the class"); let ptr = - Item::builtin_type(TypeKind::Pointer(class), is_const, ctx); + Item::builtin_type(TypeKind::Pointer(class.as_type_id_unchecked()), is_const, ctx); args.insert(0, (Some("this".into()), ptr)); } else if is_virtual { let void = Item::builtin_type(TypeKind::Void, false, ctx); let ptr = - Item::builtin_type(TypeKind::Pointer(void), false, ctx); + Item::builtin_type(TypeKind::Pointer(void.as_type_id_unchecked()), false, ctx); args.insert(0, (Some("this".into()), ptr)); } } diff --git a/src/ir/item.rs b/src/ir/item.rs index 955793c135..38d562fbe0 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -156,7 +156,9 @@ impl<'a> Iterator for ItemAncestorsIter<'a> { } } -impl AsTemplateParam for ItemId { +impl AsTemplateParam for T +where + T: Copy + Into { type Extra = (); fn as_template_param( @@ -164,7 +166,7 @@ impl AsTemplateParam for ItemId { ctx: &BindgenContext, _: &(), ) -> Option { - ctx.resolve_item(*self).as_template_param(ctx, &()) + ctx.resolve_item((*self).into()).as_template_param(ctx, &()) } } @@ -952,7 +954,10 @@ impl Item { } } -impl IsOpaque for ItemId { +impl IsOpaque for T +where + T: Copy + Into +{ type Extra = (); fn is_opaque(&self, ctx: &BindgenContext, _: &()) -> bool { @@ -960,7 +965,7 @@ impl IsOpaque for ItemId { ctx.in_codegen_phase(), "You're not supposed to call this yet" ); - ctx.resolve_item(*self).is_opaque(ctx, &()) + ctx.resolve_item((*self).into()).is_opaque(ctx, &()) } } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 301f543d8c..341466589f 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -1,7 +1,7 @@ //! Everything related to types in our intermediate representation. use super::comp::CompInfo; -use super::context::{BindgenContext, ItemId}; +use super::context::{BindgenContext, ItemId, TypeId}; use super::dot::DotAttributes; use super::enum_ty::Enum; use super::function::FunctionSig; @@ -212,10 +212,10 @@ impl Type { pub fn is_incomplete_array(&self, ctx: &BindgenContext) -> Option { match self.kind { TypeKind::Array(item, len) => { - if len == 0 { Some(item) } else { None } + if len == 0 { Some(item.into()) } else { None } } TypeKind::ResolvedTypeRef(inner) => { - ctx.resolve_type(inner.as_type_id_unchecked()).is_incomplete_array(ctx) + ctx.resolve_type(inner).is_incomplete_array(ctx) } _ => None, } @@ -238,7 +238,7 @@ impl Type { )) } TypeKind::ResolvedTypeRef(inner) => { - ctx.resolve_type(inner.as_type_id_unchecked()).layout(ctx) + ctx.resolve_type(inner).layout(ctx) } _ => None, } @@ -275,8 +275,8 @@ impl Type { ctx: &BindgenContext, ) -> Option> { let name_info = match *self.kind() { - TypeKind::Pointer(inner) => Some((inner, Cow::Borrowed("ptr"))), - TypeKind::Reference(inner) => Some((inner, Cow::Borrowed("ref"))), + TypeKind::Pointer(inner) => Some((inner.into(), Cow::Borrowed("ptr"))), + TypeKind::Reference(inner) => Some((inner.into(), Cow::Borrowed("ref"))), TypeKind::Array(inner, length) => { Some((inner, format!("array{}", length).into())) } @@ -333,7 +333,7 @@ impl Type { TypeKind::ResolvedTypeRef(inner) | TypeKind::Alias(inner) | TypeKind::TemplateAlias(inner, _) => { - ctx.resolve_type(inner.as_type_id_unchecked()).safe_canonical_type(ctx) + ctx.resolve_type(inner).safe_canonical_type(ctx) } TypeKind::TemplateInstantiation(ref inst) => { ctx.resolve_type(inst.template_definition().as_type_id_unchecked()) @@ -546,7 +546,7 @@ impl TemplateParameters for TypeKind { ) -> Option> { match *self { TypeKind::ResolvedTypeRef(id) => { - ctx.resolve_type(id.as_type_id_unchecked()).self_template_params(ctx) + ctx.resolve_type(id).self_template_params(ctx) } TypeKind::Comp(ref comp) => comp.self_template_params(ctx), TypeKind::TemplateAlias(_, ref args) => Some(args.clone()), @@ -626,14 +626,14 @@ pub enum TypeKind { Complex(FloatKind), /// A type alias, with a name, that points to another type. - Alias(ItemId), + Alias(TypeId), /// A templated alias, pointing to an inner type, just as `Alias`, but with /// template parameters. - TemplateAlias(ItemId, Vec), + TemplateAlias(TypeId, Vec), - /// An array of a type and a lenght. - Array(ItemId, usize), + /// An array of a type and a length. + Array(TypeId, usize), /// A function type, with a given signature. Function(FunctionSig), @@ -643,13 +643,13 @@ pub enum TypeKind { /// A pointer to a type. The bool field represents whether it's const or /// not. - Pointer(ItemId), + Pointer(TypeId), /// A pointer to an Apple block. BlockPointer, /// A reference to a type, as in: int& foo(). - Reference(ItemId), + Reference(TypeId), /// An instantiation of an abstract template definition with a set of /// concrete template arguments. @@ -673,7 +673,7 @@ pub enum TypeKind { /// /// These are generated after we resolve a forward declaration, or when we /// replace one type with another. - ResolvedTypeRef(ItemId), + ResolvedTypeRef(TypeId), /// A named type, that is, a template parameter. TypeParam, @@ -701,12 +701,12 @@ impl Type { TypeKind::Comp(ref ci) => ci.is_unsized(ctx, itemid), TypeKind::Opaque => self.layout.map_or(true, |l| l.size == 0), TypeKind::Array(inner, size) => { - size == 0 || ctx.resolve_type(inner.as_type_id_unchecked()).is_unsized(ctx, &inner) + size == 0 || ctx.resolve_type(inner).is_unsized(ctx, &inner.into()) } TypeKind::ResolvedTypeRef(inner) | TypeKind::Alias(inner) | TypeKind::TemplateAlias(inner, _) => { - ctx.resolve_type(inner.as_type_id_unchecked()).is_unsized(ctx, &inner) + ctx.resolve_type(inner).is_unsized(ctx, &inner.into()) } TypeKind::TemplateInstantiation(ref inst) => { let definition = inst.template_definition(); @@ -1000,7 +1000,7 @@ impl Type { } }; - TypeKind::TemplateAlias(inner_type, args) + TypeKind::TemplateAlias(inner_type.as_type_id_unchecked(), args) } CXCursor_TemplateRef => { let referenced = location.referenced().unwrap(); @@ -1116,7 +1116,7 @@ impl Type { } let inner = Item::from_ty_or_ref(pointee, location, None, ctx); - TypeKind::Pointer(inner) + TypeKind::Pointer(inner.as_type_id_unchecked()) } CXType_BlockPointer => TypeKind::BlockPointer, // XXX: RValueReference is most likely wrong, but I don't think we @@ -1129,7 +1129,7 @@ impl Type { None, ctx, ); - TypeKind::Reference(inner) + TypeKind::Reference(inner.as_type_id_unchecked()) } // XXX DependentSizedArray is wrong CXType_VariableArray | @@ -1140,7 +1140,7 @@ impl Type { None, ctx, ).expect("Not able to resolve array element?"); - TypeKind::Pointer(inner) + TypeKind::Pointer(inner.as_type_id_unchecked()) } CXType_IncompleteArray => { let inner = Item::from_ty( @@ -1149,7 +1149,7 @@ impl Type { None, ctx, ).expect("Not able to resolve array element?"); - TypeKind::Array(inner, 0) + TypeKind::Array(inner.as_type_id_unchecked(), 0) } CXType_FunctionNoProto | CXType_FunctionProto => { @@ -1161,7 +1161,7 @@ impl Type { let inner = cursor.typedef_type().expect("Not valid Type?"); let inner = Item::from_ty_or_ref(inner, location, None, ctx); - TypeKind::Alias(inner) + TypeKind::Alias(inner.as_type_id_unchecked()) } CXType_Enum => { let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?"); @@ -1207,7 +1207,7 @@ impl Type { None, ctx, ).expect("Not able to resolve array element?"); - TypeKind::Array(inner, ty.num_elements().unwrap()) + TypeKind::Array(inner.as_type_id_unchecked(), ty.num_elements().unwrap()) } CXType_Elaborated => { return Self::from_clang_ty( @@ -1261,10 +1261,10 @@ impl Trace for Type { TypeKind::Array(inner, _) | TypeKind::Alias(inner) | TypeKind::ResolvedTypeRef(inner) => { - tracer.visit_kind(inner, EdgeKind::TypeReference); + tracer.visit_kind(inner.into(), EdgeKind::TypeReference); } TypeKind::TemplateAlias(inner, ref template_params) => { - tracer.visit_kind(inner, EdgeKind::TypeReference); + tracer.visit_kind(inner.into(), EdgeKind::TypeReference); for &item in template_params { tracer.visit_kind( item, diff --git a/src/ir/var.rs b/src/ir/var.rs index 5fafd72d4c..c0ecf3e4c3 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -179,7 +179,7 @@ impl ClangSubItemParser for Var { true, ctx, ); - (TypeKind::Pointer(char_ty), VarType::String(val)) + (TypeKind::Pointer(char_ty.as_type_id_unchecked()), VarType::String(val)) } EvalResult::Int(Wrapping(value)) => { let kind = ctx.parse_callbacks() From 25ce0f658775bc866179c291e2f0c85f797a5b6b Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 16:16:19 -0700 Subject: [PATCH 06/25] Make TemplateInstantiation's definition into a TypeId The definition of a template is always a type, so it should be a TypeId rather than an ItemId. Template arguments, on the other hand are not guaranteed to be types. They can be constant values, for example. --- src/ir/analysis/derive_copy.rs | 2 +- src/ir/analysis/derive_debug.rs | 2 +- src/ir/analysis/derive_default.rs | 2 +- src/ir/analysis/derive_hash.rs | 2 +- src/ir/analysis/derive_partial_eq_or_partial_ord.rs | 2 +- src/ir/analysis/has_destructor.rs | 2 +- src/ir/analysis/has_float.rs | 2 +- src/ir/analysis/has_type_param_in_array.rs | 2 +- src/ir/analysis/has_vtable.rs | 2 +- src/ir/analysis/template_params.rs | 10 +++++----- src/ir/context.rs | 4 ++-- src/ir/template.rs | 12 ++++++------ src/ir/ty.rs | 4 ++-- 13 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index 1a97f3c2d0..319f67cdf4 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -307,7 +307,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { "The early ty.is_opaque check should have handled this case" ); let def_cannot_derive = self.is_not_copy( - template.template_definition(), + template.template_definition().into(), ); if def_cannot_derive { trace!( diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs index 8a83613be5..0ca94cd1db 100644 --- a/src/ir/analysis/derive_debug.rs +++ b/src/ir/analysis/derive_debug.rs @@ -325,7 +325,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { "The early ty.is_opaque check should have handled this case" ); let def_cannot_derive = self.is_not_debug( - template.template_definition(), + template.template_definition().into(), ); if def_cannot_derive { trace!( diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs index 083723c77b..aff9968183 100644 --- a/src/ir/analysis/derive_default.rs +++ b/src/ir/analysis/derive_default.rs @@ -353,7 +353,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { "The early ty.is_opaque check should have handled this case" ); let def_cannot_derive = - self.is_not_default(template.template_definition()); + self.is_not_default(template.template_definition().into()); if def_cannot_derive { trace!( " template definition cannot derive Default, so \ diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index e2aae2f8bb..6644ad49c2 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -326,7 +326,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { "The early ty.is_opaque check should have handled this case" ); let def_cannot_derive = self.cannot_derive_hash.contains( - &template.template_definition(), + &template.template_definition().into(), ); if def_cannot_derive { trace!( diff --git a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs index 9211bb0925..14e6cd9b1f 100644 --- a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs +++ b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs @@ -348,7 +348,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { "The early ty.is_opaque check should have handled this case" ); let def_cannot_derive = self.cannot_derive_partialeq_or_partialord.contains( - &template.template_definition(), + &template.template_definition().into(), ); if def_cannot_derive { trace!( diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs index 4058cd883e..2d3bb89fca 100644 --- a/src/ir/analysis/has_destructor.rs +++ b/src/ir/analysis/has_destructor.rs @@ -140,7 +140,7 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> { TypeKind::TemplateInstantiation(ref inst) => { let definition_or_arg_destructor = - self.have_destructor.contains(&inst.template_definition()) + self.have_destructor.contains(&inst.template_definition().into()) || inst.template_arguments().iter().any(|arg| { self.have_destructor.contains(arg) diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs index 218572dc7a..0f0fb38520 100644 --- a/src/ir/analysis/has_float.rs +++ b/src/ir/analysis/has_float.rs @@ -205,7 +205,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { } let def_has = self.has_float - .contains(&template.template_definition()); + .contains(&template.template_definition().into()); if def_has { trace!(" template definition has float, so \ insantiation also has"); diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs index 6a0e670791..09783037e9 100644 --- a/src/ir/analysis/has_type_param_in_array.rs +++ b/src/ir/analysis/has_type_param_in_array.rs @@ -217,7 +217,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { } let def_has = self.has_type_parameter_in_array.contains( - &template.template_definition(), + &template.template_definition().into(), ); if def_has { trace!( diff --git a/src/ir/analysis/has_vtable.rs b/src/ir/analysis/has_vtable.rs index 53a647af1d..3d44dd9242 100644 --- a/src/ir/analysis/has_vtable.rs +++ b/src/ir/analysis/has_vtable.rs @@ -120,7 +120,7 @@ impl<'ctx> MonotoneFramework for HasVtableAnalysis<'ctx> { } TypeKind::TemplateInstantiation(ref inst) => { - if self.have_vtable.contains(&inst.template_definition()) { + if self.have_vtable.contains(&inst.template_definition().into()) { self.insert(id) } else { ConstrainResult::Same diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs index ea4bd7b8a9..d7f5ab5795 100644 --- a/src/ir/analysis/template_params.rs +++ b/src/ir/analysis/template_params.rs @@ -271,14 +271,14 @@ impl<'ctx> UsedTemplateParameters<'ctx> { ) { trace!(" template instantiation"); - let decl = self.ctx.resolve_type(instantiation.template_definition().as_type_id_unchecked()); + let decl = self.ctx.resolve_type(instantiation.template_definition()); let args = instantiation.template_arguments(); let params = decl.self_template_params(self.ctx).unwrap_or(vec![]); - debug_assert!(this_id != instantiation.template_definition()); + debug_assert!(this_id != instantiation.template_definition().into()); let used_by_def = self.used - .get(&instantiation.template_definition()) + .get(&instantiation.template_definition().into()) .expect("Should have a used entry for instantiation's template definition") .as_ref() .expect("And it should be Some because only this_id's set is None, and an \ @@ -411,7 +411,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // generic template parameters are used. ctx.resolve_item(item).as_type().map(|ty| match ty.kind() { &TypeKind::TemplateInstantiation(ref inst) => { - let decl = ctx.resolve_type(inst.template_definition().as_type_id_unchecked()); + let decl = ctx.resolve_type(inst.template_definition()); let args = inst.template_arguments(); // Although template definitions should always have @@ -520,7 +520,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // template definition uses the corresponding template parameter. Some(&TypeKind::TemplateInstantiation(ref inst)) => { if self.whitelisted_items.contains( - &inst.template_definition(), + &inst.template_definition().into(), ) { self.constrain_instantiation( diff --git a/src/ir/context.rs b/src/ir/context.rs index 79f4012e78..2fef35eed3 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1509,7 +1509,7 @@ impl BindgenContext { let sub_name = Some(template_decl_cursor.spelling()); let sub_inst = TemplateInstantiation::new( - template_decl_id, + template_decl_id.as_type_id_unchecked(), sub_args, ); let sub_kind = @@ -1578,7 +1578,7 @@ impl BindgenContext { args.reverse(); let type_kind = TypeKind::TemplateInstantiation( - TemplateInstantiation::new(template, args), + TemplateInstantiation::new(template.as_type_id_unchecked(), args), ); let name = ty.spelling(); let name = if name.is_empty() { None } else { Some(name) }; diff --git a/src/ir/template.rs b/src/ir/template.rs index c1650abc1b..bad3df4897 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -27,7 +27,7 @@ //! }; //! ``` -use super::context::{BindgenContext, ItemId}; +use super::context::{BindgenContext, ItemId, TypeId}; use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath}; use super::traversal::{EdgeKind, Trace, Tracer}; use clang; @@ -206,7 +206,7 @@ pub trait AsTemplateParam { #[derive(Clone, Debug)] pub struct TemplateInstantiation { /// The template definition which this is instantiating. - definition: ItemId, + definition: TypeId, /// The concrete template arguments, which will be substituted in the /// definition for the generic template parameters. args: Vec, @@ -215,7 +215,7 @@ pub struct TemplateInstantiation { impl TemplateInstantiation { /// Construct a new template instantiation from the given parts. pub fn new( - template_definition: ItemId, + template_definition: TypeId, template_args: I, ) -> TemplateInstantiation where @@ -228,7 +228,7 @@ impl TemplateInstantiation { } /// Get the template definition for this instantiation. - pub fn template_definition(&self) -> ItemId { + pub fn template_definition(&self) -> TypeId { self.definition } @@ -305,7 +305,7 @@ impl TemplateInstantiation { Item::from_ty_or_ref(definition.cur_type(), definition, None, ctx); Some(TemplateInstantiation::new( - template_definition, + template_definition.as_type_id_unchecked(), template_args, )) } @@ -353,7 +353,7 @@ impl Trace for TemplateInstantiation { where T: Tracer, { - tracer.visit_kind(self.definition, EdgeKind::TemplateDeclaration); + tracer.visit_kind(self.definition.into(), EdgeKind::TemplateDeclaration); for &item in self.template_arguments() { tracer.visit_kind(item, EdgeKind::TemplateArgument); } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 341466589f..1bb2cce764 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -336,7 +336,7 @@ impl Type { ctx.resolve_type(inner).safe_canonical_type(ctx) } TypeKind::TemplateInstantiation(ref inst) => { - ctx.resolve_type(inst.template_definition().as_type_id_unchecked()) + ctx.resolve_type(inst.template_definition()) .safe_canonical_type(ctx) } @@ -710,7 +710,7 @@ impl Type { } TypeKind::TemplateInstantiation(ref inst) => { let definition = inst.template_definition(); - ctx.resolve_type(definition.as_type_id_unchecked()).is_unsized(ctx, &definition) + ctx.resolve_type(definition).is_unsized(ctx, &definition.into()) } TypeKind::TypeParam | TypeKind::Int(..) | From 2a0cee7e01ca7fb993ba4b2feaab51e343583be6 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 16:29:00 -0700 Subject: [PATCH 07/25] Make functions which take an ItemId generic to take any kind of id --- src/codegen/mod.rs | 8 ++--- src/ir/analysis/derive_copy.rs | 12 ++++--- src/ir/analysis/derive_debug.rs | 12 ++++--- src/ir/analysis/derive_default.rs | 12 ++++--- src/ir/analysis/derive_hash.rs | 3 +- .../derive_partial_eq_or_partial_ord.rs | 3 +- src/ir/analysis/has_destructor.rs | 3 +- src/ir/analysis/has_float.rs | 3 +- src/ir/analysis/has_type_param_in_array.rs | 3 +- src/ir/analysis/has_vtable.rs | 3 +- src/ir/analysis/template_params.rs | 3 +- src/ir/context.rs | 31 +++++++++++++------ src/ir/item.rs | 6 ++-- 13 files changed, 63 insertions(+), 39 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index b0c1b18e27..fef5d027d0 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -151,12 +151,12 @@ impl<'a> CodegenResult<'a> { self.saw_objc = true; } - fn seen(&self, item: ItemId) -> bool { - self.items_seen.contains(&item) + fn seen>(&self, item: Id) -> bool { + self.items_seen.contains(&item.into()) } - fn set_seen(&mut self, item: ItemId) { - self.items_seen.insert(item); + fn set_seen>(&mut self, item: Id) { + self.items_seen.insert(item.into()); } fn seen_function(&self, name: &str) -> bool { diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index 319f67cdf4..e4241b5b5e 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -73,7 +73,8 @@ impl<'ctx> CannotDeriveCopy<'ctx> { } } - fn insert(&mut self, id: ItemId) -> ConstrainResult { + fn insert>(&mut self, id: Id) -> ConstrainResult { + let id = id.into(); trace!("inserting {:?} into the cannot_derive_copy set", id); let was_not_already_in_set = self.cannot_derive_copy.insert(id); @@ -89,7 +90,8 @@ impl<'ctx> CannotDeriveCopy<'ctx> { /// A type is not `Copy` if we've determined it is not copy, or if it is /// blacklisted. - fn is_not_copy(&self, id: ItemId) -> bool { + fn is_not_copy>(&self, id: Id) -> bool { + let id = id.into(); self.cannot_derive_copy.contains(&id) || !self.ctx.whitelisted_items().contains(&id) } @@ -177,7 +179,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { } TypeKind::Array(t, len) => { - let cant_derive_copy = self.is_not_copy(t.into()); + let cant_derive_copy = self.is_not_copy(t); if cant_derive_copy { trace!( " arrays of T for which we cannot derive Copy \ @@ -198,7 +200,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - let cant_derive_copy = self.is_not_copy(t.into()); + let cant_derive_copy = self.is_not_copy(t); if cant_derive_copy { trace!( " arrays of T for which we cannot derive Copy \ @@ -307,7 +309,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { "The early ty.is_opaque check should have handled this case" ); let def_cannot_derive = self.is_not_copy( - template.template_definition().into(), + template.template_definition() ); if def_cannot_derive { trace!( diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs index 0ca94cd1db..a1743ae950 100644 --- a/src/ir/analysis/derive_debug.rs +++ b/src/ir/analysis/derive_debug.rs @@ -74,7 +74,8 @@ impl<'ctx> CannotDeriveDebug<'ctx> { } } - fn insert(&mut self, id: ItemId) -> ConstrainResult { + fn insert>(&mut self, id: Id) -> ConstrainResult { + let id = id.into(); trace!("inserting {:?} into the cannot_derive_debug set", id); let was_not_already_in_set = self.cannot_derive_debug.insert(id); @@ -90,7 +91,8 @@ impl<'ctx> CannotDeriveDebug<'ctx> { /// A type is not `Debug` if we've determined it is not debug, or if it is /// blacklisted. - fn is_not_debug(&self, id: ItemId) -> bool { + fn is_not_debug>(&self, id: Id) -> bool { + let id = id.into(); self.cannot_derive_debug.contains(&id) || !self.ctx.whitelisted_items().contains(&id) } @@ -191,7 +193,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { } TypeKind::Array(t, len) => { - if self.is_not_debug(t.into()) { + if self.is_not_debug(t) { trace!( " arrays of T for which we cannot derive Debug \ also cannot derive Debug" @@ -211,7 +213,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - if self.is_not_debug(t.into()) { + if self.is_not_debug(t) { trace!( " aliases and type refs to T which cannot derive \ Debug also cannot derive Debug" @@ -325,7 +327,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> { "The early ty.is_opaque check should have handled this case" ); let def_cannot_derive = self.is_not_debug( - template.template_definition().into(), + template.template_definition() ); if def_cannot_derive { trace!( diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs index aff9968183..4c208b3701 100644 --- a/src/ir/analysis/derive_default.rs +++ b/src/ir/analysis/derive_default.rs @@ -71,7 +71,8 @@ impl<'ctx> CannotDeriveDefault<'ctx> { } } - fn insert(&mut self, id: ItemId) -> ConstrainResult { + fn insert>(&mut self, id: Id) -> ConstrainResult { + let id = id.into(); trace!("inserting {:?} into the cannot_derive_default set", id); let was_not_already_in_set = self.cannot_derive_default.insert(id); @@ -85,7 +86,8 @@ impl<'ctx> CannotDeriveDefault<'ctx> { ConstrainResult::Changed } - fn is_not_default(&self, id: ItemId) -> bool { + fn is_not_default>(&self, id: Id) -> bool { + let id = id.into(); self.cannot_derive_default.contains(&id) || !self.ctx.whitelisted_items().contains(&id) } @@ -222,7 +224,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { } TypeKind::Array(t, len) => { - if self.is_not_default(t.into()) { + if self.is_not_default(t) { trace!( " arrays of T for which we cannot derive Default \ also cannot derive Default" @@ -242,7 +244,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateAlias(t, _) | TypeKind::Alias(t) => { - if self.is_not_default(t.into()) { + if self.is_not_default(t) { trace!( " aliases and type refs to T which cannot derive \ Default also cannot derive Default" @@ -353,7 +355,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { "The early ty.is_opaque check should have handled this case" ); let def_cannot_derive = - self.is_not_default(template.template_definition().into()); + self.is_not_default(template.template_definition()); if def_cannot_derive { trace!( " template definition cannot derive Default, so \ diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index 6644ad49c2..1cbd85fb5d 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -74,7 +74,8 @@ impl<'ctx> CannotDeriveHash<'ctx> { } } - fn insert(&mut self, id: ItemId) -> ConstrainResult { + fn insert>(&mut self, id: Id) -> ConstrainResult { + let id = id.into(); trace!("inserting {:?} into the cannot_derive_hash set", id); let was_not_already_in_set = self.cannot_derive_hash.insert(id); diff --git a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs index 14e6cd9b1f..6750dc3b92 100644 --- a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs +++ b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs @@ -83,7 +83,8 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { } } - fn insert(&mut self, id: ItemId) -> ConstrainResult { + fn insert>(&mut self, id: Id) -> ConstrainResult { + let id = id.into(); trace!("inserting {:?} into the cannot_derive_partialeq_or_partialord set", id); let was_not_already_in_set = self.cannot_derive_partialeq_or_partialord.insert(id); diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs index 2d3bb89fca..28537b71eb 100644 --- a/src/ir/analysis/has_destructor.rs +++ b/src/ir/analysis/has_destructor.rs @@ -54,7 +54,8 @@ impl<'ctx> HasDestructorAnalysis<'ctx> { } } - fn insert(&mut self, id: ItemId) -> ConstrainResult { + fn insert>(&mut self, id: Id) -> ConstrainResult { + let id = id.into(); let was_not_already_in_set = self.have_destructor.insert(id); assert!( was_not_already_in_set, diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs index 0f0fb38520..60c53b7d54 100644 --- a/src/ir/analysis/has_float.rs +++ b/src/ir/analysis/has_float.rs @@ -62,7 +62,8 @@ impl<'ctx> HasFloat<'ctx> { } } - fn insert(&mut self, id: ItemId) -> ConstrainResult { + fn insert>(&mut self, id: Id) -> ConstrainResult { + let id = id.into(); trace!("inserting {:?} into the has_float set", id); let was_not_already_in_set = self.has_float.insert(id); diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs index 09783037e9..ce1ed77f71 100644 --- a/src/ir/analysis/has_type_param_in_array.rs +++ b/src/ir/analysis/has_type_param_in_array.rs @@ -64,7 +64,8 @@ impl<'ctx> HasTypeParameterInArray<'ctx> { } } - fn insert(&mut self, id: ItemId) -> ConstrainResult { + fn insert>(&mut self, id: Id) -> ConstrainResult { + let id = id.into(); trace!( "inserting {:?} into the has_type_parameter_in_array set", id diff --git a/src/ir/analysis/has_vtable.rs b/src/ir/analysis/has_vtable.rs index 3d44dd9242..a0615daf53 100644 --- a/src/ir/analysis/has_vtable.rs +++ b/src/ir/analysis/has_vtable.rs @@ -47,7 +47,8 @@ impl<'ctx> HasVtableAnalysis<'ctx> { } } - fn insert(&mut self, id: ItemId) -> ConstrainResult { + fn insert>(&mut self, id: Id) -> ConstrainResult { + let id = id.into(); let was_not_already_in_set = self.have_vtable.insert(id); assert!( was_not_already_in_set, diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs index d7f5ab5795..5298624360 100644 --- a/src/ir/analysis/template_params.rs +++ b/src/ir/analysis/template_params.rs @@ -203,7 +203,8 @@ impl<'ctx> UsedTemplateParameters<'ctx> { } } - fn take_this_id_usage_set(&mut self, this_id: ItemId) -> ItemSet { + fn take_this_id_usage_set>(&mut self, this_id: Id) -> ItemSet { + let this_id = this_id.into(); self.used .get_mut(&this_id) .expect( diff --git a/src/ir/context.rs b/src/ir/context.rs index 2fef35eed3..45d8ed138f 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1840,7 +1840,8 @@ impl BindgenContext { /// Is the item with the given `name` blacklisted? Or is the item with the given /// `name` and `id` replaced by another type, and effectively blacklisted? - pub fn blacklisted_by_name(&self, path: &[String], id: ItemId) -> bool { + pub fn blacklisted_by_name>(&self, path: &[String], id: Id) -> bool { + let id = id.into(); debug_assert!( self.in_codegen_phase(), "You're not supposed to call this yet" @@ -1851,7 +1852,8 @@ impl BindgenContext { /// Has the item with the given `name` and `id` been replaced by another /// type? - pub fn is_replaced_type(&self, path: &[String], id: ItemId) -> bool { + pub fn is_replaced_type>(&self, path: &[String], id: Id) -> bool { + let id = id.into(); match self.replacements.get(path) { Some(replaced_by) if *replaced_by != id => true, _ => false, @@ -2133,7 +2135,8 @@ impl BindgenContext { /// Look up whether the item with `id` can /// derive debug or not. - pub fn lookup_item_id_can_derive_debug(&self, id: ItemId) -> bool { + pub fn lookup_item_id_can_derive_debug>(&self, id: Id) -> bool { + let id = id.into(); assert!( self.in_codegen_phase(), "We only compute can_derive_debug when we enter codegen" @@ -2156,7 +2159,8 @@ impl BindgenContext { /// Look up whether the item with `id` can /// derive default or not. - pub fn lookup_item_id_can_derive_default(&self, id: ItemId) -> bool { + pub fn lookup_item_id_can_derive_default>(&self, id: Id) -> bool { + let id = id.into(); assert!( self.in_codegen_phase(), "We only compute can_derive_default when we enter codegen" @@ -2185,7 +2189,8 @@ impl BindgenContext { /// Look up whether the item with `id` can /// derive hash or not. - pub fn lookup_item_id_can_derive_hash(&self, id: ItemId) -> bool { + pub fn lookup_item_id_can_derive_hash>(&self, id: Id) -> bool { + let id = id.into(); assert!( self.in_codegen_phase(), "We only compute can_derive_debug when we enter codegen" @@ -2206,7 +2211,8 @@ impl BindgenContext { } /// Look up whether the item with `id` can derive `Partial{Eq,Ord}`. - pub fn lookup_item_id_can_derive_partialeq_or_partialord(&self, id: ItemId) -> bool { + pub fn lookup_item_id_can_derive_partialeq_or_partialord>(&self, id: Id) -> bool { + let id = id.into(); assert!( self.in_codegen_phase(), "We only compute can_derive_partialeq_or_partialord when we enter codegen" @@ -2298,15 +2304,19 @@ impl TypeId { } } -impl From for ItemResolver { - fn from(id: ItemId) -> ItemResolver { +impl From for ItemResolver +where + T: Into +{ + fn from(id: T) -> ItemResolver { ItemResolver::new(id) } } impl ItemResolver { /// Construct a new `ItemResolver` from the given id. - pub fn new(id: ItemId) -> ItemResolver { + pub fn new>(id: Id) -> ItemResolver { + let id = id.into(); ItemResolver { id: id, through_type_refs: false, @@ -2361,7 +2371,8 @@ pub struct PartialType { impl PartialType { /// Construct a new `PartialType`. - pub fn new(decl: Cursor, id: ItemId) -> PartialType { + pub fn new>(decl: Cursor, id: Id) -> PartialType { + let id = id.into(); // assert!(decl == decl.canonical()); PartialType { decl: decl, diff --git a/src/ir/item.rs b/src/ir/item.rs index 38d562fbe0..6baf5a06dd 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -111,7 +111,7 @@ cfg_if! { DebugOnlyItemSet } - fn contains(&self,_id: &ItemId) -> bool { + fn contains(&self, _id: &ItemId) -> bool { false } @@ -474,8 +474,8 @@ impl Item { /// Set this item's parent id. /// /// This is only used so replacements get generated in the proper module. - pub fn set_parent_for_replacement(&mut self, id: ItemId) { - self.parent_id = id; + pub fn set_parent_for_replacement>(&mut self, id: Id) { + self.parent_id = id.into(); } /// Returns the depth this item is indented to. From 95d97416475666fa8975289deb3b90eb1724cc03 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 16:50:25 -0700 Subject: [PATCH 08/25] Make comp fields contain `TypeId`s --- src/codegen/mod.rs | 2 +- src/ir/analysis/derive_default.rs | 4 +- src/ir/analysis/derive_hash.rs | 8 +-- .../derive_partial_eq_or_partial_ord.rs | 8 +-- src/ir/analysis/has_destructor.rs | 2 +- src/ir/analysis/has_float.rs | 4 +- src/ir/analysis/has_type_param_in_array.rs | 2 +- src/ir/comp.rs | 38 ++++++------- src/ir/context.rs | 55 +++++++++++++------ src/ir/item.rs | 24 +++++--- src/ir/var.rs | 12 ++-- 11 files changed, 93 insertions(+), 66 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index fef5d027d0..22abad10f6 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1112,7 +1112,7 @@ impl Bitfield { ctor_impl: quote::Tokens, unit_field_int_ty: "e::Tokens, ) -> quote::Tokens { - let bitfield_ty = ctx.resolve_type(self.ty().as_type_id_unchecked()); + let bitfield_ty = ctx.resolve_type(self.ty()); let bitfield_ty_layout = bitfield_ty.layout(ctx).expect( "Bitfield without layout? Gah!", ); diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs index 4c208b3701..13ab29a469 100644 --- a/src/ir/analysis/derive_default.rs +++ b/src/ir/analysis/derive_default.rs @@ -305,7 +305,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { info.fields().iter().any(|f| match *f { Field::DataMember(ref data) => { !self.ctx.whitelisted_items().contains( - &data.ty(), + &data.ty().into(), ) || self.is_not_default(data.ty()) } @@ -320,7 +320,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { bfu.bitfields().iter().any(|b| { !self.ctx.whitelisted_items().contains( - &b.ty(), + &b.ty().into(), ) || self.is_not_default(b.ty()) }) diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index 1cbd85fb5d..0d4392b33c 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -279,9 +279,9 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { info.fields().iter().any(|f| match *f { Field::DataMember(ref data) => { !self.ctx.whitelisted_items().contains( - &data.ty(), + &data.ty().into(), ) || - self.cannot_derive_hash.contains(&data.ty()) + self.cannot_derive_hash.contains(&data.ty().into()) } Field::Bitfields(ref bfu) => { if bfu.layout().align > RUST_DERIVE_IN_ARRAY_LIMIT { @@ -294,9 +294,9 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { bfu.bitfields().iter().any(|b| { !self.ctx.whitelisted_items().contains( - &b.ty(), + &b.ty().into(), ) || - self.cannot_derive_hash.contains(&b.ty()) + self.cannot_derive_hash.contains(&b.ty().into()) }) } }); diff --git a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs index 6750dc3b92..f5cdc566fb 100644 --- a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs +++ b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs @@ -295,10 +295,10 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { info.fields().iter().any(|f| match *f { Field::DataMember(ref data) => { !self.ctx.whitelisted_items().contains( - &data.ty(), + &data.ty().into(), ) || self.cannot_derive_partialeq_or_partialord.contains( - &data.ty(), + &data.ty().into(), ) } Field::Bitfields(ref bfu) => { @@ -312,10 +312,10 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { bfu.bitfields().iter().any(|b| { !self.ctx.whitelisted_items().contains( - &b.ty(), + &b.ty().into(), ) || self.cannot_derive_partialeq_or_partialord.contains( - &b.ty(), + &b.ty().into(), ) }) } diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs index 28537b71eb..9966b7f267 100644 --- a/src/ir/analysis/has_destructor.rs +++ b/src/ir/analysis/has_destructor.rs @@ -126,7 +126,7 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> { info.fields().iter().any(|field| { match *field { Field::DataMember(ref data) => - self.have_destructor.contains(&data.ty()), + self.have_destructor.contains(&data.ty().into()), Field::Bitfields(_) => false } }); diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs index 60c53b7d54..8b86f48d94 100644 --- a/src/ir/analysis/has_float.rs +++ b/src/ir/analysis/has_float.rs @@ -176,12 +176,12 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { .any(|f| { match *f { Field::DataMember(ref data) => { - self.has_float.contains(&data.ty()) + self.has_float.contains(&data.ty().into()) } Field::Bitfields(ref bfu) => { bfu.bitfields() .iter().any(|b| { - self.has_float.contains(&b.ty()) + self.has_float.contains(&b.ty().into()) }) }, } diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs index ce1ed77f71..30e2f48bf1 100644 --- a/src/ir/analysis/has_type_param_in_array.rs +++ b/src/ir/analysis/has_type_param_in_array.rs @@ -191,7 +191,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { } let fields_have = info.fields().iter().any(|f| match *f { Field::DataMember(ref data) => { - self.has_type_parameter_in_array.contains(&data.ty()) + self.has_type_parameter_in_array.contains(&data.ty().into()) } Field::Bitfields(..) => false, }); diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 1bc53d1d8c..7d3da4c599 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1,7 +1,7 @@ //! Compound types (unions and structs) in our intermediate representation. use super::annotations::Annotations; -use super::context::{BindgenContext, ItemId}; +use super::context::{BindgenContext, ItemId, TypeId}; use super::dot::DotAttributes; use super::item::{IsOpaque, Item}; use super::layout::Layout; @@ -110,7 +110,7 @@ pub trait FieldMethods { fn name(&self) -> Option<&str>; /// Get the type of this field. - fn ty(&self) -> ItemId; + fn ty(&self) -> TypeId; /// Get the comment for this field. fn comment(&self) -> Option<&str>; @@ -176,7 +176,7 @@ impl Field { layout, .. }) => Some(layout), Field::DataMember(ref data) => { - ctx.resolve_type(data.ty.as_type_id_unchecked()).layout(ctx) + ctx.resolve_type(data.ty).layout(ctx) } } } @@ -191,13 +191,13 @@ impl Trace for Field { { match *self { Field::DataMember(ref data) => { - tracer.visit_kind(data.ty, EdgeKind::Field); + tracer.visit_kind(data.ty.into(), EdgeKind::Field); } Field::Bitfields(BitfieldUnit { ref bitfields, .. }) => { for bf in bitfields { - tracer.visit_kind(bf.ty(), EdgeKind::Field); + tracer.visit_kind(bf.ty().into(), EdgeKind::Field); } } } @@ -343,7 +343,7 @@ impl FieldMethods for Bitfield { self.data.name() } - fn ty(&self) -> ItemId { + fn ty(&self) -> TypeId { self.data.ty() } @@ -380,7 +380,7 @@ impl RawField { /// Construct a new `RawField`. fn new( name: Option, - ty: ItemId, + ty: TypeId, comment: Option, annotations: Option, bitfield: Option, @@ -404,7 +404,7 @@ impl FieldMethods for RawField { self.0.name() } - fn ty(&self) -> ItemId { + fn ty(&self) -> TypeId { self.0.ty() } @@ -538,7 +538,7 @@ fn bitfields_to_allocation_units( for bitfield in raw_bitfields { let bitfield_width = bitfield.bitfield().unwrap() as usize; - let bitfield_layout = ctx.resolve_type(bitfield.ty().as_type_id_unchecked()) + let bitfield_layout = ctx.resolve_type(bitfield.ty()) .layout(ctx) .expect("Bitfield without layout? Gah!"); let bitfield_size = bitfield_layout.size; @@ -705,7 +705,7 @@ impl Trace for CompFields { match *self { CompFields::BeforeComputingBitfieldUnits(ref fields) => { for f in fields { - tracer.visit_kind(f.ty(), EdgeKind::Field); + tracer.visit_kind(f.ty().into(), EdgeKind::Field); } } CompFields::AfterComputingBitfieldUnits(ref fields) => { @@ -724,7 +724,7 @@ pub struct FieldData { name: Option, /// The inner type. - ty: ItemId, + ty: TypeId, /// The doc comment on the field if any. comment: Option, @@ -747,7 +747,7 @@ impl FieldMethods for FieldData { self.name.as_ref().map(|n| &**n) } - fn ty(&self) -> ItemId { + fn ty(&self) -> TypeId { self.ty } @@ -1104,12 +1104,12 @@ impl CompInfo { let name = if name.is_empty() { None } else { Some(name) }; let field = RawField::new(name, - field_type, - comment, - annotations, - bit_width, - is_mutable, - offset); + field_type.as_type_id_unchecked(), + comment, + annotations, + bit_width, + is_mutable, + offset); ci.fields.append_raw_field(field); // No we look for things like attributes and stuff. @@ -1163,7 +1163,7 @@ impl CompInfo { let ty = cur.cur_type(); let offset = cur.offset_of_field().ok(); maybe_anonymous_struct_field = - Some((inner, ty, offset)); + Some((inner.as_type_id_unchecked(), ty, offset)); } } CXCursor_PackedAttr => { diff --git a/src/ir/context.rs b/src/ir/context.rs index 45d8ed138f..2aed6872af 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -9,8 +9,7 @@ use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd, CanDerivePartialEq, CanDeriveEq}; use super::int::IntKind; -use super::item::{HasTypeParamInArray, IsOpaque, Item, ItemAncestors, - ItemCanonicalPath, ItemSet}; +use super::item::{IsOpaque, Item, ItemAncestors, ItemCanonicalPath, ItemSet}; use super::item_kind::ItemKind; use super::module::{Module, ModuleKind}; use super::template::{TemplateInstantiation, TemplateParameters}; @@ -81,20 +80,29 @@ impl ItemId { } } -impl CanDeriveDebug for ItemId { +impl CanDeriveDebug for T +where + T: Copy + Into +{ fn can_derive_debug(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_debug && ctx.lookup_item_id_can_derive_debug(*self) } } -impl CanDeriveDefault for ItemId { +impl CanDeriveDefault for T +where + T: Copy + Into +{ fn can_derive_default(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_default && ctx.lookup_item_id_can_derive_default(*self) } } -impl<'a> CanDeriveCopy<'a> for ItemId { +impl<'a, T> CanDeriveCopy<'a> for T +where + T: Copy + Into +{ fn can_derive_copy(&self, ctx: &BindgenContext) -> bool { ctx.lookup_item_id_can_derive_copy(*self) } @@ -106,33 +114,45 @@ impl CanDeriveHash for ItemId { } } -impl CanDerivePartialOrd for ItemId { +impl CanDerivePartialOrd for T +where + T: Copy + Into +{ fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_partialord && ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) } } -impl CanDerivePartialEq for ItemId { +impl CanDerivePartialEq for T +where + T: Copy + Into +{ fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_partialeq && ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) } } -impl CanDeriveEq for ItemId { +impl CanDeriveEq for T +where + T: Copy + Into +{ fn can_derive_eq(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_eq && ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) && - !ctx.lookup_item_id_has_float(&self) + !ctx.lookup_item_id_has_float(*self) } } -impl CanDeriveOrd for ItemId { +impl CanDeriveOrd for T +where + T: Copy + Into +{ fn can_derive_ord(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_ord && ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) && - !ctx.lookup_item_id_has_float(&self) + !ctx.lookup_item_id_has_float(*self) } } @@ -2224,7 +2244,7 @@ impl BindgenContext { } /// Look up whether the item with `id` can derive `Copy` or not. - pub fn lookup_item_id_can_derive_copy(&self, id: ItemId) -> bool { + pub fn lookup_item_id_can_derive_copy>(&self, id: Id) -> bool { assert!( self.in_codegen_phase(), "We only compute can_derive_debug when we enter codegen" @@ -2232,7 +2252,8 @@ impl BindgenContext { // Look up the computed value for whether the item with `id` can // derive `Copy` or not. - !id.has_type_param_in_array(self) && + let id = id.into(); + !self.lookup_item_id_has_type_param_in_array(id) && !self.cannot_derive_copy.as_ref().unwrap().contains(&id) } @@ -2245,7 +2266,7 @@ impl BindgenContext { } /// Look up whether the item with `id` has type parameter in array or not. - pub fn lookup_item_id_has_type_param_in_array(&self, id: &ItemId) -> bool { + pub fn lookup_item_id_has_type_param_in_array>(&self, id: Id) -> bool { assert!( self.in_codegen_phase(), "We only compute has array when we enter codegen" @@ -2253,7 +2274,7 @@ impl BindgenContext { // Look up the computed value for whether the item with `id` has // type parameter in array or not. - self.has_type_param_in_array.as_ref().unwrap().contains(id) + self.has_type_param_in_array.as_ref().unwrap().contains(&id.into()) } /// Compute whether the type has float. @@ -2266,13 +2287,13 @@ impl BindgenContext { } /// Look up whether the item with `id` has array or not. - pub fn lookup_item_id_has_float(&self, id: &ItemId) -> bool { + pub fn lookup_item_id_has_float>(&self, id: Id) -> bool { assert!(self.in_codegen_phase(), "We only compute has float when we enter codegen"); // Look up the computed value for whether the item with `id` has // float or not. - self.has_float.as_ref().unwrap().contains(id) + self.has_float.as_ref().unwrap().contains(&id.into()) } /// Check if `--no-partialeq` flag is enabled for this item. diff --git a/src/ir/item.rs b/src/ir/item.rs index 6baf5a06dd..8a38675308 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -291,7 +291,7 @@ impl Trace for Item { tracer.visit(fun.signature()); } ItemKind::Var(ref var) => { - tracer.visit_kind(var.ty(), EdgeKind::VarType); + tracer.visit_kind(var.ty().into(), EdgeKind::VarType); } ItemKind::Module(_) => { // Module -> children edges are "weak", and we do not want to @@ -351,7 +351,7 @@ impl CanDeriveEq for Item { fn can_derive_eq(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_eq && ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) && - !ctx.lookup_item_id_has_float(&self.id()) + !ctx.lookup_item_id_has_float(self.id()) } } @@ -359,7 +359,7 @@ impl CanDeriveOrd for Item { fn can_derive_ord(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_ord && ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) && - !ctx.lookup_item_id_has_float(&self.id()) + !ctx.lookup_item_id_has_float(self.id()) } } @@ -995,13 +995,16 @@ impl HasVtable for Item { } } -impl HasTypeParamInArray for ItemId { +impl HasTypeParamInArray for T +where + T: Copy + Into +{ fn has_type_param_in_array(&self, ctx: &BindgenContext) -> bool { debug_assert!( ctx.in_codegen_phase(), "You're not supposed to call this yet" ); - ctx.lookup_item_id_has_type_param_in_array(self) + ctx.lookup_item_id_has_type_param_in_array(*self) } } @@ -1011,15 +1014,18 @@ impl HasTypeParamInArray for Item { ctx.in_codegen_phase(), "You're not supposed to call this yet" ); - ctx.lookup_item_id_has_type_param_in_array(&self.id()) + ctx.lookup_item_id_has_type_param_in_array(self.id()) } } -impl HasFloat for ItemId { +impl HasFloat for T +where + T: Copy + Into +{ fn has_float(&self, ctx: &BindgenContext) -> bool { debug_assert!(ctx.in_codegen_phase(), "You're not supposed to call this yet"); - ctx.lookup_item_id_has_float(self) + ctx.lookup_item_id_has_float(*self) } } @@ -1027,7 +1033,7 @@ impl HasFloat for Item { fn has_float(&self, ctx: &BindgenContext) -> bool { debug_assert!(ctx.in_codegen_phase(), "You're not supposed to call this yet"); - ctx.lookup_item_id_has_float(&self.id()) + ctx.lookup_item_id_has_float(self.id()) } } diff --git a/src/ir/var.rs b/src/ir/var.rs index c0ecf3e4c3..d66504f6c6 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -1,6 +1,6 @@ //! Intermediate representation of variables. -use super::context::{BindgenContext, ItemId}; +use super::context::{BindgenContext, TypeId}; use super::dot::DotAttributes; use super::function::cursor_mangling; use super::int::IntKind; @@ -35,7 +35,7 @@ pub struct Var { /// The mangled name of the variable. mangled_name: Option, /// The type of the variable. - ty: ItemId, + ty: TypeId, /// The value of the variable, that needs to be suitable for `ty`. val: Option, /// Whether this variable is const. @@ -47,7 +47,7 @@ impl Var { pub fn new( name: String, mangled: Option, - ty: ItemId, + ty: TypeId, val: Option, is_const: bool, ) -> Var { @@ -72,7 +72,7 @@ impl Var { } /// Get this variable's type. - pub fn ty(&self) -> ItemId { + pub fn ty(&self) -> TypeId { self.ty } @@ -203,7 +203,7 @@ impl ClangSubItemParser for Var { let ty = Item::builtin_type(type_kind, true, ctx); Ok(ParseResult::New( - Var::new(name, None, ty, Some(val), true), + Var::new(name, None, ty.as_type_id_unchecked(), Some(val), true), Some(cursor), )) } @@ -278,7 +278,7 @@ impl ClangSubItemParser for Var { }; let mangling = cursor_mangling(ctx, &cursor); - let var = Var::new(name, mangling, ty, value, is_const); + let var = Var::new(name, mangling, ty.as_type_id_unchecked(), value, is_const); Ok(ParseResult::New(var, Some(cursor))) } From 3e869f17fb00ef85025450c0017de5ea7e60e188 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 17:03:44 -0700 Subject: [PATCH 09/25] Make a bunch more methods take generic ids --- src/codegen/mod.rs | 12 ++++++------ src/ir/comp.rs | 12 ++++++------ src/ir/context.rs | 13 ++++++++----- src/ir/item.rs | 39 ++++++++++++++++++++++++++++----------- src/ir/ty.rs | 5 +++-- 5 files changed, 51 insertions(+), 30 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 22abad10f6..acc87692a6 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -6,6 +6,7 @@ pub mod struct_layout; use self::helpers::attributes; use self::struct_layout::StructLayoutTracker; +use ir::analysis::HasVtable; use ir::annotations::FieldAccessorKind; use ir::comment; use ir::comp::{Base, Bitfield, BitfieldUnit, CompInfo, CompKind, Field, @@ -1546,7 +1547,7 @@ impl CodeGenerator for CompInfo { // NB: We won't include unsized types in our base chain because they // would contribute to our size given the dummy field we insert for // unsized types. - if base_ty.is_unsized(ctx, &base.ty) { + if base_ty.is_unsized(ctx, base.ty) { continue; } @@ -1625,7 +1626,7 @@ impl CodeGenerator for CompInfo { warn!("Opaque type without layout! Expect dragons!"); } } - } else if !is_union && !self.is_unsized(ctx, &item.id()) { + } else if !is_union && !self.is_unsized(ctx, item.id()) { if let Some(padding_field) = layout.and_then(|layout| struct_layout.pad_struct(layout)) { @@ -1649,7 +1650,7 @@ impl CodeGenerator for CompInfo { // // NOTE: This check is conveniently here to avoid the dummy fields we // may add for unused template parameters. - if self.is_unsized(ctx, &item.id()) { + if self.is_unsized(ctx, item.id()) { let has_address = if is_opaque { // Generate the address field if it's an opaque type and // couldn't determine the layout of the blob. @@ -1758,9 +1759,8 @@ impl CodeGenerator for CompInfo { // FIXME when [issue #465](https://github.com/rust-lang-nursery/rust-bindgen/issues/465) ready let too_many_base_vtables = self.base_members() .iter() - .filter(|base| ctx.lookup_item_id_has_vtable(&base.ty)) - .count() > - 1; + .filter(|base| base.ty.has_vtable(ctx)) + .count() > 1; let should_skip_field_offset_checks = is_opaque || too_many_base_vtables; diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 7d3da4c599..5cbcaf09a7 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1,5 +1,6 @@ //! Compound types (unions and structs) in our intermediate representation. +use super::analysis::HasVtable; use super::annotations::Annotations; use super::context::{BindgenContext, ItemId, TypeId}; use super::dot::DotAttributes; @@ -910,12 +911,12 @@ impl CompInfo { } /// Is this compound type unsized? - pub fn is_unsized(&self, ctx: &BindgenContext, itemid: &ItemId) -> bool { - !ctx.lookup_item_id_has_vtable(itemid) && self.fields().is_empty() && + pub fn is_unsized>(&self, ctx: &BindgenContext, id: Id) -> bool { + !ctx.lookup_item_id_has_vtable(id.into()) && self.fields().is_empty() && self.base_members.iter().all(|base| { ctx.resolve_type(base.ty.as_type_id_unchecked()).canonical_type(ctx).is_unsized( ctx, - &base.ty, + base.ty, ) }) } @@ -1354,8 +1355,7 @@ impl CompInfo { ctx: &BindgenContext, item: &Item, ) -> bool { - ctx.lookup_item_id_has_vtable(&item.id()) && - !self.base_members.iter().any(|base| { + item.has_vtable(ctx) && !self.base_members.iter().any(|base| { // NB: Ideally, we could rely in all these types being `comp`, and // life would be beautiful. // @@ -1365,7 +1365,7 @@ impl CompInfo { ctx.resolve_type(base.ty.as_type_id_unchecked()) .canonical_type(ctx) .as_comp() - .map_or(false, |_| ctx.lookup_item_id_has_vtable(&base.ty)) + .map_or(false, |_| base.ty.has_vtable(ctx)) }) } diff --git a/src/ir/context.rs b/src/ir/context.rs index 2aed6872af..5c3530a66f 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -108,7 +108,10 @@ where } } -impl CanDeriveHash for ItemId { +impl CanDeriveHash for T +where + T: Copy + Into +{ fn can_derive_hash(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_hash && ctx.lookup_item_id_can_derive_hash(*self) } @@ -1122,7 +1125,7 @@ impl BindgenContext { } /// Look up whether the item with `id` has vtable or not. - pub fn lookup_item_id_has_vtable(&self, id: &ItemId) -> bool { + pub fn lookup_item_id_has_vtable>(&self, id: Id) -> bool { assert!( self.in_codegen_phase(), "We only compute vtables when we enter codegen" @@ -1130,7 +1133,7 @@ impl BindgenContext { // Look up the computed value for whether the item with `id` has a // vtable or not. - self.have_vtable.as_ref().unwrap().contains(id) + self.have_vtable.as_ref().unwrap().contains(&id.into()) } /// Compute whether the type has a destructor. @@ -1282,8 +1285,8 @@ impl BindgenContext { /// Resolve the given `ItemId` into an `Item`, or `None` if no such item /// exists. - pub fn resolve_item_fallible(&self, item_id: ItemId) -> Option<&Item> { - self.items.get(&item_id) + pub fn resolve_item_fallible>(&self, id: Id) -> Option<&Item> { + self.items.get(&id.into()) } /// Resolve the given `ItemId` into an `Item`. diff --git a/src/ir/item.rs b/src/ir/item.rs index 8a38675308..27c08fa07c 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -128,9 +128,9 @@ pub struct ItemAncestorsIter<'a> { } impl<'a> ItemAncestorsIter<'a> { - fn new(ctx: &'a BindgenContext, item: ItemId) -> Self { + fn new>(ctx: &'a BindgenContext, id: Id) -> Self { ItemAncestorsIter { - item: item, + item: id.into(), ctx: ctx, seen: DebugOnlyItemSet::new(), } @@ -199,8 +199,10 @@ impl AsTemplateParam for ItemKind { } } -// Pure convenience -impl ItemCanonicalName for ItemId { +impl ItemCanonicalName for T +where + T: Copy + Into +{ fn canonical_name(&self, ctx: &BindgenContext) -> String { debug_assert!( ctx.in_codegen_phase(), @@ -210,7 +212,10 @@ impl ItemCanonicalName for ItemId { } } -impl ItemCanonicalPath for ItemId { +impl ItemCanonicalPath for T + where + T: Copy + Into +{ fn namespace_aware_canonical_path( &self, ctx: &BindgenContext, @@ -231,7 +236,10 @@ impl ItemCanonicalPath for ItemId { } } -impl ItemAncestors for ItemId { +impl ItemAncestors for T +where + T: Copy + Into +{ fn ancestors<'a>( &self, ctx: &'a BindgenContext, @@ -249,7 +257,10 @@ impl ItemAncestors for Item { } } -impl Trace for ItemId { +impl Trace for Id +where + Id: Copy + Into +{ type Extra = (); fn trace(&self, ctx: &BindgenContext, tracer: &mut T, extra: &()) @@ -983,15 +994,18 @@ impl IsOpaque for Item { } } -impl HasVtable for ItemId { +impl HasVtable for T +where + T: Copy + Into +{ fn has_vtable(&self, ctx: &BindgenContext) -> bool { - ctx.lookup_item_id_has_vtable(self) + ctx.lookup_item_id_has_vtable(*self) } } impl HasVtable for Item { fn has_vtable(&self, ctx: &BindgenContext) -> bool { - ctx.lookup_item_id_has_vtable(&self.id()) + ctx.lookup_item_id_has_vtable(self.id()) } } @@ -1065,7 +1079,10 @@ impl DotAttributes for Item { } } -impl TemplateParameters for ItemId { +impl TemplateParameters for T +where + T: Copy + Into +{ fn self_template_params( &self, ctx: &BindgenContext, diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 1bb2cce764..d119e9e4b3 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -693,12 +693,13 @@ impl Type { /// derive whether we should generate a dummy `_address` field for structs, /// to comply to the C and C++ layouts, that specify that every type needs /// to be addressable. - pub fn is_unsized(&self, ctx: &BindgenContext, itemid: &ItemId) -> bool { + pub fn is_unsized>(&self, ctx: &BindgenContext, id: Id) -> bool { debug_assert!(ctx.in_codegen_phase(), "Not yet"); + let id = id.into(); match self.kind { TypeKind::Void => true, - TypeKind::Comp(ref ci) => ci.is_unsized(ctx, itemid), + TypeKind::Comp(ref ci) => ci.is_unsized(ctx, id), TypeKind::Opaque => self.layout.map_or(true, |l| l.size == 0), TypeKind::Array(inner, size) => { size == 0 || ctx.resolve_type(inner).is_unsized(ctx, &inner.into()) From c2e94bea0a8c569fe3f41c654f3ab4ecfb6ff62e Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 17:06:18 -0700 Subject: [PATCH 10/25] Make base members use TypeId rather than ItemId --- src/codegen/mod.rs | 2 +- src/ir/analysis/derive_default.rs | 2 +- src/ir/analysis/derive_hash.rs | 4 ++-- src/ir/analysis/derive_partial_eq_or_partial_ord.rs | 4 ++-- src/ir/analysis/has_destructor.rs | 2 +- src/ir/analysis/has_float.rs | 2 +- src/ir/analysis/has_type_param_in_array.rs | 2 +- src/ir/analysis/has_vtable.rs | 2 +- src/ir/comp.rs | 10 +++++----- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index acc87692a6..95ec8f9dc4 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1543,7 +1543,7 @@ impl CodeGenerator for CompInfo { continue; } - let base_ty = ctx.resolve_type(base.ty.as_type_id_unchecked()); + let base_ty = ctx.resolve_type(base.ty); // NB: We won't include unsized types in our base chain because they // would contribute to our size given the dummy field we insert for // unsized types. diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs index 13ab29a469..f8f02df75d 100644 --- a/src/ir/analysis/derive_default.rs +++ b/src/ir/analysis/derive_default.rs @@ -290,7 +290,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { let bases_cannot_derive = info.base_members().iter().any(|base| { - !self.ctx.whitelisted_items().contains(&base.ty) || + !self.ctx.whitelisted_items().contains(&base.ty.into()) || self.is_not_default(base.ty) }); if bases_cannot_derive { diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index 0d4392b33c..8e23f73fff 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -264,8 +264,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { let bases_cannot_derive = info.base_members().iter().any(|base| { - !self.ctx.whitelisted_items().contains(&base.ty) || - self.cannot_derive_hash.contains(&base.ty) + !self.ctx.whitelisted_items().contains(&base.ty.into()) || + self.cannot_derive_hash.contains(&base.ty.into()) }); if bases_cannot_derive { trace!( diff --git a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs index f5cdc566fb..ccdbbb690d 100644 --- a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs +++ b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs @@ -280,8 +280,8 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { let bases_cannot_derive = info.base_members().iter().any(|base| { - !self.ctx.whitelisted_items().contains(&base.ty) || - self.cannot_derive_partialeq_or_partialord.contains(&base.ty) + !self.ctx.whitelisted_items().contains(&base.ty.into()) || + self.cannot_derive_partialeq_or_partialord.contains(&base.ty.into()) }); if bases_cannot_derive { trace!( diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs index 9966b7f267..729910beda 100644 --- a/src/ir/analysis/has_destructor.rs +++ b/src/ir/analysis/has_destructor.rs @@ -121,7 +121,7 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> { CompKind::Struct => { let base_or_field_destructor = info.base_members().iter().any(|base| { - self.have_destructor.contains(&base.ty) + self.have_destructor.contains(&base.ty.into()) }) || info.fields().iter().any(|field| { match *field { diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs index 8b86f48d94..05dd3b4aca 100644 --- a/src/ir/analysis/has_float.rs +++ b/src/ir/analysis/has_float.rs @@ -166,7 +166,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { TypeKind::Comp(ref info) => { let bases_have = info.base_members() .iter() - .any(|base| self.has_float.contains(&base.ty)); + .any(|base| self.has_float.contains(&base.ty.into())); if bases_have { trace!(" bases have float, so we also have"); return self.insert(id); diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs index 30e2f48bf1..238ffe6032 100644 --- a/src/ir/analysis/has_type_param_in_array.rs +++ b/src/ir/analysis/has_type_param_in_array.rs @@ -183,7 +183,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { TypeKind::Comp(ref info) => { let bases_have = info.base_members().iter().any(|base| { - self.has_type_parameter_in_array.contains(&base.ty) + self.has_type_parameter_in_array.contains(&base.ty.into()) }); if bases_have { trace!(" bases have array, so we also have"); diff --git a/src/ir/analysis/has_vtable.rs b/src/ir/analysis/has_vtable.rs index a0615daf53..92d6a38f78 100644 --- a/src/ir/analysis/has_vtable.rs +++ b/src/ir/analysis/has_vtable.rs @@ -111,7 +111,7 @@ impl<'ctx> MonotoneFramework for HasVtableAnalysis<'ctx> { return self.insert(id); } let bases_has_vtable = info.base_members().iter().any(|base| { - self.have_vtable.contains(&base.ty) + self.have_vtable.contains(&base.ty.into()) }); if bases_has_vtable { self.insert(id) diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 5cbcaf09a7..d0641a2be3 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -794,7 +794,7 @@ pub enum BaseKind { #[derive(Clone, Debug)] pub struct Base { /// The type of this base class. - pub ty: ItemId, + pub ty: TypeId, /// The kind of inheritance we're doing. pub kind: BaseKind, /// Name of the field in which this base should be stored. @@ -914,7 +914,7 @@ impl CompInfo { pub fn is_unsized>(&self, ctx: &BindgenContext, id: Id) -> bool { !ctx.lookup_item_id_has_vtable(id.into()) && self.fields().is_empty() && self.base_members.iter().all(|base| { - ctx.resolve_type(base.ty.as_type_id_unchecked()).canonical_type(ctx).is_unsized( + ctx.resolve_type(base.ty).canonical_type(ctx).is_unsized( ctx, base.ty, ) @@ -1193,7 +1193,7 @@ impl CompInfo { let type_id = Item::from_ty_or_ref(cur.cur_type(), cur, None, ctx); ci.base_members.push(Base { - ty: type_id, + ty: type_id.as_type_id_unchecked(), kind: kind, field_name: field_name, }); @@ -1362,7 +1362,7 @@ impl CompInfo { // Unfortunately, given the way we implement --match-pat, and also // that you can inherit from templated types, we need to handle // other cases here too. - ctx.resolve_type(base.ty.as_type_id_unchecked()) + ctx.resolve_type(base.ty) .canonical_type(ctx) .as_comp() .map_or(false, |_| base.ty.has_vtable(ctx)) @@ -1513,7 +1513,7 @@ impl Trace for CompInfo { } for base in self.base_members() { - tracer.visit_kind(base.ty, EdgeKind::BaseMember); + tracer.visit_kind(base.ty.into(), EdgeKind::BaseMember); } self.fields.trace(context, tracer, &()); From d83e732f20296aed45968606bc6cd020f25cb450 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 17:08:59 -0700 Subject: [PATCH 11/25] `instantiate_template` should take a `TypeId` for the template definition --- src/ir/context.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ir/context.rs b/src/ir/context.rs index 5c3530a66f..2f2a6346bd 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1425,13 +1425,13 @@ impl BindgenContext { fn instantiate_template( &mut self, with_id: ItemId, - template: ItemId, + template: TypeId, ty: &clang::Type, location: clang::Cursor, ) -> Option { use clang_sys; - let num_expected_args = match self.resolve_type(template.as_type_id_unchecked()) + let num_expected_args = match self.resolve_type(template) .num_self_template_params(self) { Some(n) => n, None => { @@ -1485,7 +1485,7 @@ impl BindgenContext { let ty = Item::from_ty_or_ref( child.cur_type(), *child, - Some(template), + Some(template.into()), self, ); args.push(ty); @@ -1507,7 +1507,7 @@ impl BindgenContext { let ty = Item::from_ty_or_ref( child.cur_type(), *child, - Some(template), + Some(template.into()), self, ); args.push(ty); @@ -1601,7 +1601,7 @@ impl BindgenContext { args.reverse(); let type_kind = TypeKind::TemplateInstantiation( - TemplateInstantiation::new(template.as_type_id_unchecked(), args), + TemplateInstantiation::new(template, args), ); let name = ty.spelling(); let name = if name.is_empty() { None } else { Some(name) }; @@ -1699,7 +1699,7 @@ impl BindgenContext { return None; } - return self.instantiate_template(with_id, id, ty, location) + return self.instantiate_template(with_id, id.as_type_id_unchecked(), ty, location) .or_else(|| Some(id)); } From 5e753975ce8685c22ce78fb993c0db1819de2dfb Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 17:11:43 -0700 Subject: [PATCH 12/25] Make `Enum::repr` into a `TypeId` --- src/codegen/mod.rs | 2 +- src/ir/enum_ty.rs | 10 +++++----- src/ir/ty.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 95ec8f9dc4..3d07e1d03a 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2318,7 +2318,7 @@ impl CodeGenerator for Enum { let enum_ty = item.expect_type(); let layout = enum_ty.layout(ctx); - let repr = self.repr().map(|repr| ctx.resolve_type(repr.as_type_id_unchecked())); + let repr = self.repr().map(|repr| ctx.resolve_type(repr)); let repr = match repr { Some(repr) => { match *repr.canonical_type(ctx).kind() { diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index c02f01636e..a23b6491fc 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -1,6 +1,6 @@ //! Intermediate representation for C/C++ enumerations. -use super::context::{BindgenContext, ItemId}; +use super::context::{BindgenContext, TypeId}; use super::item::Item; use super::ty::TypeKind; use clang; @@ -27,7 +27,7 @@ pub struct Enum { /// /// It's `None` if the enum is a forward declaration and isn't defined /// anywhere else, see `tests/headers/func_ptr_in_struct.h`. - repr: Option, + repr: Option, /// The different variants, with explicit values. variants: Vec, @@ -35,7 +35,7 @@ pub struct Enum { impl Enum { /// Construct a new `Enum` with the given representation and variants. - pub fn new(repr: Option, variants: Vec) -> Self { + pub fn new(repr: Option, variants: Vec) -> Self { Enum { repr: repr, variants: variants, @@ -43,7 +43,7 @@ impl Enum { } /// Get this enumeration's representation. - pub fn repr(&self) -> Option { + pub fn repr(&self) -> Option { self.repr } @@ -125,7 +125,7 @@ impl Enum { } CXChildVisit_Continue }); - Ok(Enum::new(repr, variants)) + Ok(Enum::new(repr.map(|r| r.as_type_id_unchecked()), variants)) } /// Whether the enum should be a bitfield diff --git a/src/ir/ty.rs b/src/ir/ty.rs index d119e9e4b3..54d7be6c86 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -1280,7 +1280,7 @@ impl Trace for Type { TypeKind::Function(ref sig) => sig.trace(context, tracer, &()), TypeKind::Enum(ref en) => { if let Some(repr) = en.repr() { - tracer.visit(repr); + tracer.visit(repr.into()); } } TypeKind::UnresolvedTypeRef(_, _, Some(id)) => { From 9ad1e6aac88880170d5c4486c7e9ac1c877c46f7 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 17:42:29 -0700 Subject: [PATCH 13/25] A bunch of parsing things should return TypeId --- src/codegen/mod.rs | 4 +- src/ir/analysis/derive_hash.rs | 2 +- .../derive_partial_eq_or_partial_ord.rs | 2 +- src/ir/analysis/has_destructor.rs | 2 +- src/ir/analysis/has_float.rs | 2 +- src/ir/analysis/has_type_param_in_array.rs | 2 +- src/ir/analysis/template_params.rs | 2 +- src/ir/comp.rs | 10 ++-- src/ir/context.rs | 58 +++++++++---------- src/ir/enum_ty.rs | 4 +- src/ir/function.rs | 30 +++++----- src/ir/item.rs | 48 +++++++-------- src/ir/template.rs | 20 +++---- src/ir/ty.rs | 36 ++++++------ src/ir/var.rs | 8 +-- src/parse.rs | 14 ++--- 16 files changed, 122 insertions(+), 122 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 3d07e1d03a..ce5054c982 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -690,7 +690,7 @@ impl CodeGenerator for Type { let params: Vec<_> = params.into_iter() .filter_map(|p| p.as_template_param(ctx, &())) .collect(); - if params.iter().any(|p| ctx.resolve_type(p.as_type_id_unchecked()).is_invalid_type_param()) { + if params.iter().any(|p| ctx.resolve_type(*p).is_invalid_type_param()) { warn!( "Item contained invalid template \ parameter: {:?}", @@ -1674,7 +1674,7 @@ impl CodeGenerator for CompInfo { let mut param_names = vec![]; for (idx, ty) in params.iter().enumerate() { - let param = ctx.resolve_type(ty.as_type_id_unchecked()); + let param = ctx.resolve_type(*ty); let name = param.name().unwrap(); let ident = ctx.rust_ident(name); param_names.push(ident.clone()); diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index 8e23f73fff..569c724612 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -312,7 +312,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { TypeKind::TemplateInstantiation(ref template) => { let args_cannot_derive = template.template_arguments().iter().any(|arg| { - self.cannot_derive_hash.contains(&arg) + self.cannot_derive_hash.contains(&arg.into()) }); if args_cannot_derive { trace!( diff --git a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs index ccdbbb690d..7efce6e578 100644 --- a/src/ir/analysis/derive_partial_eq_or_partial_ord.rs +++ b/src/ir/analysis/derive_partial_eq_or_partial_ord.rs @@ -334,7 +334,7 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> { TypeKind::TemplateInstantiation(ref template) => { let args_cannot_derive = template.template_arguments().iter().any(|arg| { - self.cannot_derive_partialeq_or_partialord.contains(&arg) + self.cannot_derive_partialeq_or_partialord.contains(&arg.into()) }); if args_cannot_derive { trace!( diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs index 729910beda..c87b7e2580 100644 --- a/src/ir/analysis/has_destructor.rs +++ b/src/ir/analysis/has_destructor.rs @@ -144,7 +144,7 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> { self.have_destructor.contains(&inst.template_definition().into()) || inst.template_arguments().iter().any(|arg| { - self.have_destructor.contains(arg) + self.have_destructor.contains(&arg.into()) }); if definition_or_arg_destructor { self.insert(id) diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs index 05dd3b4aca..193862c0b9 100644 --- a/src/ir/analysis/has_float.rs +++ b/src/ir/analysis/has_float.rs @@ -198,7 +198,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> { TypeKind::TemplateInstantiation(ref template) => { let args_have = template.template_arguments() .iter() - .any(|arg| self.has_float.contains(&arg)); + .any(|arg| self.has_float.contains(&arg.into())); if args_have { trace!(" template args have float, so \ insantiation also has float"); diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs index 238ffe6032..aa8d34be9a 100644 --- a/src/ir/analysis/has_type_param_in_array.rs +++ b/src/ir/analysis/has_type_param_in_array.rs @@ -207,7 +207,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> { TypeKind::TemplateInstantiation(ref template) => { let args_have = template.template_arguments().iter().any(|arg| { - self.has_type_parameter_in_array.contains(&arg) + self.has_type_parameter_in_array.contains(&arg.into()) }); if args_have { trace!( diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs index 5298624360..24ab4f2626 100644 --- a/src/ir/analysis/template_params.rs +++ b/src/ir/analysis/template_params.rs @@ -294,7 +294,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> { param ); - if used_by_def.contains(param) { + if used_by_def.contains(¶m.into()) { trace!(" param is used by template definition"); let arg = arg.into_resolver() diff --git a/src/ir/comp.rs b/src/ir/comp.rs index d0641a2be3..c193acaba1 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -825,7 +825,7 @@ pub struct CompInfo { /// concrete template arguments, and should always be a /// `Type(TypeKind::TypeParam(name))`. For concrete template arguments, see /// `TypeKind::TemplateInstantiation`. - template_params: Vec, + template_params: Vec, /// The method declarations inside this class, if in C++ mode. methods: Vec, @@ -1105,7 +1105,7 @@ impl CompInfo { let name = if name.is_empty() { None } else { Some(name) }; let field = RawField::new(name, - field_type.as_type_id_unchecked(), + field_type, comment, annotations, bit_width, @@ -1193,7 +1193,7 @@ impl CompInfo { let type_id = Item::from_ty_or_ref(cur.cur_type(), cur, None, ctx); ci.base_members.push(Base { - ty: type_id.as_type_id_unchecked(), + ty: type_id, kind: kind, field_name: field_name, }); @@ -1465,7 +1465,7 @@ impl TemplateParameters for CompInfo { fn self_template_params( &self, _ctx: &BindgenContext, - ) -> Option> { + ) -> Option> { if self.template_params.is_empty() { None } else { @@ -1483,7 +1483,7 @@ impl Trace for CompInfo { { let params = item.all_template_params(context).unwrap_or(vec![]); for p in params { - tracer.visit_kind(p, EdgeKind::TemplateParameterDefinition); + tracer.visit_kind(p.into(), EdgeKind::TemplateParameterDefinition); } for &ty in self.inner_types() { diff --git a/src/ir/context.rs b/src/ir/context.rs index 2f2a6346bd..a48b145f62 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -185,11 +185,11 @@ pub struct BindgenContext { /// Clang USR to type map. This is needed to be able to associate types with /// item ids during parsing. - types: HashMap, + types: HashMap, /// Maps from a cursor to the item id of the named template type parameter /// for that cursor. - type_params: HashMap, + type_params: HashMap, /// A cursor to module map. Similar reason than above. modules: HashMap, @@ -597,7 +597,7 @@ impl BindgenContext { TypeKey::Declaration(declaration) }; - let old = self.types.insert(key, id); + let old = self.types.insert(key, id.as_type_id_unchecked()); debug_assert_eq!(old, None); } } @@ -664,7 +664,7 @@ impl BindgenContext { "should not have already associated an item with the given id" ); - let old_named_ty = self.type_params.insert(definition, id); + let old_named_ty = self.type_params.insert(definition, id.as_type_id_unchecked()); assert!( old_named_ty.is_none(), "should not have already associated a named type with this id" @@ -673,7 +673,7 @@ impl BindgenContext { /// Get the named type defined at the given cursor location, if we've /// already added one. - pub fn get_type_param(&self, definition: &clang::Cursor) -> Option { + pub fn get_type_param(&self, definition: &clang::Cursor) -> Option { assert_eq!( definition.kind(), clang_sys::CXCursor_TemplateTypeParameter @@ -821,7 +821,7 @@ impl BindgenContext { let item = self.items.get_mut(&id).unwrap(); *item.kind_mut().as_type_mut().unwrap().kind_mut() = - TypeKind::ResolvedTypeRef(resolved.as_type_id_unchecked()); + TypeKind::ResolvedTypeRef(resolved); resolved }; @@ -1166,7 +1166,7 @@ impl BindgenContext { used_params.entry(id).or_insert( id.self_template_params(self).map_or( Default::default(), - |params| params.into_iter().collect(), + |params| params.into_iter().map(|p| p.into()).collect(), ), ); } @@ -1191,7 +1191,7 @@ impl BindgenContext { pub fn uses_template_parameter( &self, item: ItemId, - template_param: ItemId, + template_param: TypeId, ) -> bool { assert!( self.in_codegen_phase(), @@ -1340,7 +1340,7 @@ impl BindgenContext { fn get_declaration_info_for_template_instantiation( &self, instantiation: &Cursor, - ) -> Option<(Cursor, ItemId, usize)> { + ) -> Option<(Cursor, TypeId, usize)> { instantiation .cur_type() .canonical_declaration(Some(instantiation)) @@ -1428,7 +1428,7 @@ impl BindgenContext { template: TypeId, ty: &clang::Type, location: clang::Cursor, - ) -> Option { + ) -> Option { use clang_sys; let num_expected_args = match self.resolve_type(template) @@ -1525,14 +1525,14 @@ impl BindgenContext { return None; } - let mut sub_args: Vec<_> = args.drain( - args_len - num_expected_template_args.., - ).collect(); + let mut sub_args: Vec<_> = args + .drain(args_len - num_expected_template_args..) + .collect(); sub_args.reverse(); let sub_name = Some(template_decl_cursor.spelling()); let sub_inst = TemplateInstantiation::new( - template_decl_id.as_type_id_unchecked(), + template_decl_id, sub_args, ); let sub_kind = @@ -1564,7 +1564,7 @@ impl BindgenContext { self.add_item_to_module(&sub_item); debug_assert!(sub_id == sub_item.id()); self.items.insert(sub_id, sub_item); - args.push(sub_id); + args.push(sub_id.as_type_id_unchecked()); } } _ => { @@ -1624,7 +1624,7 @@ impl BindgenContext { self.add_item_to_module(&item); debug_assert!(with_id == item.id()); self.items.insert(with_id, item); - Some(with_id) + Some(with_id.as_type_id_unchecked()) } /// If we have already resolved the type for the given type declaration, @@ -1632,7 +1632,7 @@ impl BindgenContext { pub fn get_resolved_type( &self, decl: &clang::CanonicalTypeDeclaration, - ) -> Option { + ) -> Option { self.types .get(&TypeKey::Declaration(*decl.cursor())) .or_else(|| { @@ -1651,7 +1651,7 @@ impl BindgenContext { parent_id: Option, ty: &clang::Type, location: Option, - ) -> Option { + ) -> Option { use clang_sys::{CXCursor_TypeAliasTemplateDecl, CXCursor_TypeRef}; debug!( "builtin_or_resolved_ty: {:?}, {:?}, {:?}", @@ -1699,7 +1699,7 @@ impl BindgenContext { return None; } - return self.instantiate_template(with_id, id.as_type_id_unchecked(), ty, location) + return self.instantiate_template(with_id, id, ty, location) .or_else(|| Some(id)); } @@ -1722,14 +1722,14 @@ impl BindgenContext { pub fn build_ty_wrapper( &mut self, with_id: ItemId, - wrapped_id: ItemId, + wrapped_id: TypeId, parent_id: Option, ty: &clang::Type, - ) -> ItemId { + ) -> TypeId { let spelling = ty.spelling(); let is_const = ty.is_const(); let layout = ty.fallible_layout().ok(); - let type_kind = TypeKind::ResolvedTypeRef(wrapped_id.as_type_id_unchecked()); + let type_kind = TypeKind::ResolvedTypeRef(wrapped_id); let ty = Type::new(Some(spelling), layout, type_kind, is_const); let item = Item::new( with_id, @@ -1739,7 +1739,7 @@ impl BindgenContext { ItemKind::Type(ty), ); self.add_builtin_item(item); - with_id + with_id.as_type_id_unchecked() } /// Returns the next item id to be used for an item. @@ -1749,7 +1749,7 @@ impl BindgenContext { ret } - fn build_builtin_ty(&mut self, ty: &clang::Type) -> Option { + fn build_builtin_ty(&mut self, ty: &clang::Type) -> Option { use clang_sys::*; let type_kind = match ty.kind() { CXType_NullPtr => TypeKind::NullPtr, @@ -1801,7 +1801,7 @@ impl BindgenContext { let item = Item::new(id, None, None, self.root_module, ItemKind::Type(ty)); self.add_builtin_item(item); - Some(id) + Some(id.as_type_id_unchecked()) } /// Get the current Clang translation unit that is being processed. @@ -2390,13 +2390,13 @@ impl ItemResolver { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct PartialType { decl: Cursor, - id: ItemId, + id: TypeId, } impl PartialType { /// Construct a new `PartialType`. pub fn new>(decl: Cursor, id: Id) -> PartialType { - let id = id.into(); + let id = id.into().as_type_id_unchecked(); // assert!(decl == decl.canonical()); PartialType { decl: decl, @@ -2411,7 +2411,7 @@ impl PartialType { /// The item ID allocated for this type. This is *NOT* a key for an entry in /// the context's item set yet! - pub fn id(&self) -> ItemId { + pub fn id(&self) -> TypeId { self.id } } @@ -2420,7 +2420,7 @@ impl TemplateParameters for PartialType { fn self_template_params( &self, _ctx: &BindgenContext, - ) -> Option> { + ) -> Option> { // Maybe at some point we will eagerly parse named types, but for now we // don't and this information is unavailable. None diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index a23b6491fc..3006ec7fd5 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -72,7 +72,7 @@ impl Enum { // Assume signedness since the default type by the C standard is an int. let is_signed = repr.and_then( - |r| ctx.resolve_type(r.as_type_id_unchecked()).safe_canonical_type(ctx), + |r| ctx.resolve_type(r).safe_canonical_type(ctx), ).map_or(true, |ty| match *ty.kind() { TypeKind::Int(ref int_kind) => int_kind.is_signed(), ref other => { @@ -125,7 +125,7 @@ impl Enum { } CXChildVisit_Continue }); - Ok(Enum::new(repr.map(|r| r.as_type_id_unchecked()), variants)) + Ok(Enum::new(repr, variants)) } /// Whether the enum should be a bitfield diff --git a/src/ir/function.rs b/src/ir/function.rs index 5fcd21ea4b..990fbaff9d 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -1,7 +1,7 @@ //! Intermediate representation for C/C++ functions and methods. use super::comp::MethodKind; -use super::context::{BindgenContext, ItemId}; +use super::context::{BindgenContext, TypeId}; use super::dot::DotAttributes; use super::item::Item; use super::traversal::{EdgeKind, Trace, Tracer}; @@ -62,7 +62,7 @@ pub struct Function { mangled_name: Option, /// The id pointing to the current function signature. - signature: ItemId, + signature: TypeId, /// The doc comment on the function, if any. comment: Option, @@ -76,7 +76,7 @@ impl Function { pub fn new( name: String, mangled_name: Option, - sig: ItemId, + sig: TypeId, comment: Option, kind: FunctionKind, ) -> Self { @@ -99,8 +99,8 @@ impl Function { self.mangled_name.as_ref().map(|n| &**n) } - /// Get this function's signature. - pub fn signature(&self) -> ItemId { + /// Get this function's signature type. + pub fn signature(&self) -> TypeId { self.signature } @@ -180,11 +180,11 @@ impl quote::ToTokens for Abi { #[derive(Debug)] pub struct FunctionSig { /// The return type of the function. - return_type: ItemId, + return_type: TypeId, /// The type of the arguments, optionally with the name of the argument when /// declared. - argument_types: Vec<(Option, ItemId)>, + argument_types: Vec<(Option, TypeId)>, /// Whether this function is variadic. is_variadic: bool, @@ -287,8 +287,8 @@ pub fn cursor_mangling( impl FunctionSig { /// Construct a new function signature. pub fn new( - return_type: ItemId, - arguments: Vec<(Option, ItemId)>, + return_type: TypeId, + arguments: Vec<(Option, TypeId)>, is_variadic: bool, abi: Abi, ) -> Self { @@ -390,7 +390,7 @@ impl FunctionSig { } else if is_virtual { let void = Item::builtin_type(TypeKind::Void, false, ctx); let ptr = - Item::builtin_type(TypeKind::Pointer(void.as_type_id_unchecked()), false, ctx); + Item::builtin_type(TypeKind::Pointer(void), false, ctx); args.insert(0, (Some("this".into()), ptr)); } } @@ -412,16 +412,16 @@ impl FunctionSig { warn!("Unknown calling convention: {:?}", call_conv); } - Ok(Self::new(ret, args, ty.is_variadic(), abi)) + Ok(Self::new(ret.into(), args, ty.is_variadic(), abi)) } /// Get this function signature's return type. - pub fn return_type(&self) -> ItemId { + pub fn return_type(&self) -> TypeId { self.return_type } /// Get this function signature's argument (name, type) pairs. - pub fn argument_types(&self) -> &[(Option, ItemId)] { + pub fn argument_types(&self) -> &[(Option, TypeId)] { &self.argument_types } @@ -535,10 +535,10 @@ impl Trace for FunctionSig { where T: Tracer, { - tracer.visit_kind(self.return_type(), EdgeKind::FunctionReturn); + tracer.visit_kind(self.return_type().into(), EdgeKind::FunctionReturn); for &(_, ty) in self.argument_types() { - tracer.visit_kind(ty, EdgeKind::FunctionParameter); + tracer.visit_kind(ty.into(), EdgeKind::FunctionParameter); } } } diff --git a/src/ir/item.rs b/src/ir/item.rs index 27c08fa07c..825b9bc4d9 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -4,7 +4,7 @@ use super::analysis::HasVtable; use super::annotations::Annotations; use super::comment; use super::comp::MethodKind; -use super::context::{BindgenContext, ItemId, PartialType}; +use super::context::{BindgenContext, ItemId, PartialType, TypeId}; use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd, CanDerivePartialEq, CanDeriveEq}; @@ -165,7 +165,7 @@ where &self, ctx: &BindgenContext, _: &(), - ) -> Option { + ) -> Option { ctx.resolve_item((*self).into()).as_template_param(ctx, &()) } } @@ -177,7 +177,7 @@ impl AsTemplateParam for Item { &self, ctx: &BindgenContext, _: &(), - ) -> Option { + ) -> Option { self.kind.as_template_param(ctx, self) } } @@ -189,7 +189,7 @@ impl AsTemplateParam for ItemKind { &self, ctx: &BindgenContext, item: &Item, - ) -> Option { + ) -> Option { match *self { ItemKind::Type(ref ty) => ty.as_template_param(ctx, item), ItemKind::Module(..) | @@ -299,7 +299,7 @@ impl Trace for Item { ItemKind::Function(ref fun) => { // Just the same way, it has not real meaning for a function to // be opaque, so we trace across it. - tracer.visit(fun.signature()); + tracer.visit(fun.signature().into()); } ItemKind::Var(ref var) => { tracer.visit_kind(var.ty().into(), EdgeKind::VarType); @@ -462,12 +462,12 @@ impl Item { with_id: ItemId, ty: &clang::Type, ctx: &mut BindgenContext, - ) -> ItemId { + ) -> TypeId { let ty = Opaque::from_clang_ty(ty); let kind = ItemKind::Type(ty); let parent = ctx.root_module(); ctx.add_item(Item::new(with_id, None, None, parent, kind), None, None); - with_id + with_id.as_type_id_unchecked() } /// Get this `Item`'s identifier. @@ -1086,7 +1086,7 @@ where fn self_template_params( &self, ctx: &BindgenContext, - ) -> Option> { + ) -> Option> { ctx.resolve_item_fallible(*self).and_then(|item| { item.self_template_params(ctx) }) @@ -1097,7 +1097,7 @@ impl TemplateParameters for Item { fn self_template_params( &self, ctx: &BindgenContext, - ) -> Option> { + ) -> Option> { self.kind.self_template_params(ctx) } } @@ -1106,7 +1106,7 @@ impl TemplateParameters for ItemKind { fn self_template_params( &self, ctx: &BindgenContext, - ) -> Option> { + ) -> Option> { match *self { ItemKind::Type(ref ty) => ty.self_template_params(ctx), // If we start emitting bindings to explicitly instantiated @@ -1126,7 +1126,7 @@ fn visit_child( ty: &clang::Type, parent_id: Option, ctx: &mut BindgenContext, - result: &mut Result, + result: &mut Result, ) -> clang_sys::CXChildVisitResult { use clang_sys::*; if result.is_ok() { @@ -1150,7 +1150,7 @@ impl ClangItemParser for Item { kind: TypeKind, is_const: bool, ctx: &mut BindgenContext, - ) -> ItemId { + ) -> TypeId { // Feel free to add more here, I'm just lazy. match kind { TypeKind::Void | @@ -1168,7 +1168,7 @@ impl ClangItemParser for Item { None, None, ); - id + id.as_type_id_unchecked() } @@ -1242,7 +1242,7 @@ impl ClangItemParser for Item { cursor, parent_id, ctx, - )); + ).into()); } ctx.known_semantic_parent(definition) .or(parent_id) @@ -1257,7 +1257,7 @@ impl ClangItemParser for Item { Some(relevant_parent_id), ctx, ) { - Ok(ty) => return Ok(ty), + Ok(ty) => return Ok(ty.into()), Err(ParseError::Recurse) => return Err(ParseError::Recurse), Err(ParseError::Continue) => {} } @@ -1304,7 +1304,7 @@ impl ClangItemParser for Item { location: clang::Cursor, parent_id: Option, ctx: &mut BindgenContext, - ) -> ItemId { + ) -> TypeId { let id = ctx.next_item_id(); Self::from_ty_or_ref_with_id(id, ty, location, parent_id, ctx) } @@ -1325,7 +1325,7 @@ impl ClangItemParser for Item { location: clang::Cursor, parent_id: Option, ctx: &mut BindgenContext, - ) -> ItemId { + ) -> TypeId { debug!( "from_ty_or_ref_with_id: {:?} {:?}, {:?}, {:?}", potential_id, @@ -1374,7 +1374,7 @@ impl ClangItemParser for Item { Some(clang::Cursor::null()), None, ); - potential_id + potential_id.as_type_id_unchecked() } fn from_ty( @@ -1382,7 +1382,7 @@ impl ClangItemParser for Item { location: clang::Cursor, parent_id: Option, ctx: &mut BindgenContext, - ) -> Result { + ) -> Result { let id = ctx.next_item_id(); Item::from_ty_with_id(id, ty, location, parent_id, ctx) } @@ -1401,7 +1401,7 @@ impl ClangItemParser for Item { location: clang::Cursor, parent_id: Option, ctx: &mut BindgenContext, - ) -> Result { + ) -> Result { use clang_sys::*; debug!( @@ -1485,7 +1485,7 @@ impl ClangItemParser for Item { let result = Type::from_clang_ty(id, ty, location, parent_id, ctx); let relevant_parent_id = parent_id.unwrap_or(current_module); let ret = match result { - Ok(ParseResult::AlreadyResolved(ty)) => Ok(ty), + Ok(ParseResult::AlreadyResolved(ty)) => Ok(ty.as_type_id_unchecked()), Ok(ParseResult::New(item, declaration)) => { ctx.add_item( Item::new( @@ -1498,7 +1498,7 @@ impl ClangItemParser for Item { declaration, Some(location), ); - Ok(id) + Ok(id.as_type_id_unchecked()) } Err(ParseError::Continue) => Err(ParseError::Continue), Err(ParseError::Recurse) => { @@ -1561,7 +1561,7 @@ impl ClangItemParser for Item { with_id: Option, location: clang::Cursor, ctx: &mut BindgenContext, - ) -> Option { + ) -> Option { let ty = location.cur_type(); debug!( @@ -1724,7 +1724,7 @@ impl ClangItemParser for Item { ItemKind::Type(Type::named(name)), ); ctx.add_type_param(item, definition); - Some(id) + Some(id.as_type_id_unchecked()) } } diff --git a/src/ir/template.rs b/src/ir/template.rs index bad3df4897..f5cc015234 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -109,7 +109,7 @@ pub trait TemplateParameters { /// anything but types, so we must treat them as opaque, and avoid /// instantiating them. fn self_template_params(&self, ctx: &BindgenContext) - -> Option>; + -> Option>; /// Get the number of free template parameters this template declaration /// has. @@ -136,7 +136,7 @@ pub trait TemplateParameters { /// how we would fully reference such a member type in C++: /// `Foo::Inner`. `Foo` *must* be instantiated with template /// arguments before we can gain access to the `Inner` member type. - fn all_template_params(&self, ctx: &BindgenContext) -> Option> + fn all_template_params(&self, ctx: &BindgenContext) -> Option> where Self: ItemAncestors, { @@ -159,7 +159,7 @@ pub trait TemplateParameters { /// Get only the set of template parameters that this item uses. This is a /// subset of `all_template_params` and does not necessarily contain any of /// `self_template_params`. - fn used_template_params(&self, ctx: &BindgenContext) -> Option> + fn used_template_params(&self, ctx: &BindgenContext) -> Option> where Self: AsRef, { @@ -190,7 +190,7 @@ pub trait AsTemplateParam { &self, ctx: &BindgenContext, extra: &Self::Extra, - ) -> Option; + ) -> Option; /// Is this a named template type parameter? fn is_template_param( @@ -209,7 +209,7 @@ pub struct TemplateInstantiation { definition: TypeId, /// The concrete template arguments, which will be substituted in the /// definition for the generic template parameters. - args: Vec, + args: Vec, } impl TemplateInstantiation { @@ -219,7 +219,7 @@ impl TemplateInstantiation { template_args: I, ) -> TemplateInstantiation where - I: IntoIterator, + I: IntoIterator, { TemplateInstantiation { definition: template_definition, @@ -233,7 +233,7 @@ impl TemplateInstantiation { } /// Get the concrete template arguments used in this instantiation. - pub fn template_arguments(&self) -> &[ItemId] { + pub fn template_arguments(&self) -> &[TypeId] { &self.args[..] } @@ -305,7 +305,7 @@ impl TemplateInstantiation { Item::from_ty_or_ref(definition.cur_type(), definition, None, ctx); Some(TemplateInstantiation::new( - template_definition.as_type_id_unchecked(), + template_definition, template_args, )) } @@ -354,8 +354,8 @@ impl Trace for TemplateInstantiation { T: Tracer, { tracer.visit_kind(self.definition.into(), EdgeKind::TemplateDeclaration); - for &item in self.template_arguments() { - tracer.visit_kind(item, EdgeKind::TemplateArgument); + for arg in self.template_arguments() { + tracer.visit_kind(arg.into(), EdgeKind::TemplateArgument); } } } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 54d7be6c86..a5f3a69409 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -383,7 +383,7 @@ impl AsTemplateParam for Type { &self, ctx: &BindgenContext, item: &Item, - ) -> Option { + ) -> Option { self.kind.as_template_param(ctx, item) } } @@ -395,9 +395,9 @@ impl AsTemplateParam for TypeKind { &self, ctx: &BindgenContext, item: &Item, - ) -> Option { + ) -> Option { match *self { - TypeKind::TypeParam => Some(item.id()), + TypeKind::TypeParam => Some(item.id().as_type_id_unchecked()), TypeKind::ResolvedTypeRef(id) => id.as_template_param(ctx, &()), _ => None, } @@ -534,7 +534,7 @@ impl TemplateParameters for Type { fn self_template_params( &self, ctx: &BindgenContext, - ) -> Option> { + ) -> Option> { self.kind.self_template_params(ctx) } } @@ -543,7 +543,7 @@ impl TemplateParameters for TypeKind { fn self_template_params( &self, ctx: &BindgenContext, - ) -> Option> { + ) -> Option> { match *self { TypeKind::ResolvedTypeRef(id) => { ctx.resolve_type(id).self_template_params(ctx) @@ -630,7 +630,7 @@ pub enum TypeKind { /// A templated alias, pointing to an inner type, just as `Alias`, but with /// template parameters. - TemplateAlias(TypeId, Vec), + TemplateAlias(TypeId, Vec), /// An array of a type and a length. Array(TypeId, usize), @@ -756,7 +756,7 @@ impl Type { ); if let Some(ty) = already_resolved { debug!("{:?} already resolved: {:?}", ty, location); - return Ok(ParseResult::AlreadyResolved(ty)); + return Ok(ParseResult::AlreadyResolved(ty.into())); } } @@ -1001,7 +1001,7 @@ impl Type { } }; - TypeKind::TemplateAlias(inner_type.as_type_id_unchecked(), args) + TypeKind::TemplateAlias(inner_type, args) } CXCursor_TemplateRef => { let referenced = location.referenced().unwrap(); @@ -1036,14 +1036,14 @@ impl Type { referenced_ty ); - let item = Item::from_ty_or_ref_with_id( + let id = Item::from_ty_or_ref_with_id( potential_id, referenced_ty, declaration, parent_id, ctx, ); - return Ok(ParseResult::AlreadyResolved(item)); + return Ok(ParseResult::AlreadyResolved(id.into())); } CXCursor_NamespaceRef => { return Err(ParseError::Continue); @@ -1117,7 +1117,7 @@ impl Type { } let inner = Item::from_ty_or_ref(pointee, location, None, ctx); - TypeKind::Pointer(inner.as_type_id_unchecked()) + TypeKind::Pointer(inner) } CXType_BlockPointer => TypeKind::BlockPointer, // XXX: RValueReference is most likely wrong, but I don't think we @@ -1130,7 +1130,7 @@ impl Type { None, ctx, ); - TypeKind::Reference(inner.as_type_id_unchecked()) + TypeKind::Reference(inner) } // XXX DependentSizedArray is wrong CXType_VariableArray | @@ -1141,7 +1141,7 @@ impl Type { None, ctx, ).expect("Not able to resolve array element?"); - TypeKind::Pointer(inner.as_type_id_unchecked()) + TypeKind::Pointer(inner) } CXType_IncompleteArray => { let inner = Item::from_ty( @@ -1150,7 +1150,7 @@ impl Type { None, ctx, ).expect("Not able to resolve array element?"); - TypeKind::Array(inner.as_type_id_unchecked(), 0) + TypeKind::Array(inner, 0) } CXType_FunctionNoProto | CXType_FunctionProto => { @@ -1162,7 +1162,7 @@ impl Type { let inner = cursor.typedef_type().expect("Not valid Type?"); let inner = Item::from_ty_or_ref(inner, location, None, ctx); - TypeKind::Alias(inner.as_type_id_unchecked()) + TypeKind::Alias(inner) } CXType_Enum => { let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?"); @@ -1208,7 +1208,7 @@ impl Type { None, ctx, ).expect("Not able to resolve array element?"); - TypeKind::Array(inner.as_type_id_unchecked(), ty.num_elements().unwrap()) + TypeKind::Array(inner, ty.num_elements().unwrap()) } CXType_Elaborated => { return Self::from_clang_ty( @@ -1266,9 +1266,9 @@ impl Trace for Type { } TypeKind::TemplateAlias(inner, ref template_params) => { tracer.visit_kind(inner.into(), EdgeKind::TypeReference); - for &item in template_params { + for param in template_params { tracer.visit_kind( - item, + param.into(), EdgeKind::TemplateParameterDefinition, ); } diff --git a/src/ir/var.rs b/src/ir/var.rs index d66504f6c6..3abc44cf87 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -179,7 +179,7 @@ impl ClangSubItemParser for Var { true, ctx, ); - (TypeKind::Pointer(char_ty.as_type_id_unchecked()), VarType::String(val)) + (TypeKind::Pointer(char_ty), VarType::String(val)) } EvalResult::Int(Wrapping(value)) => { let kind = ctx.parse_callbacks() @@ -203,7 +203,7 @@ impl ClangSubItemParser for Var { let ty = Item::builtin_type(type_kind, true, ctx); Ok(ParseResult::New( - Var::new(name, None, ty.as_type_id_unchecked(), Some(val), true), + Var::new(name, None, ty, Some(val), true), Some(cursor), )) } @@ -236,7 +236,7 @@ impl ClangSubItemParser for Var { // tests/headers/inner_const.hpp // // That's fine because in that case we know it's not a literal. - let canonical_ty = ctx.safe_resolve_type(ty.as_type_id_unchecked()).and_then(|t| { + let canonical_ty = ctx.safe_resolve_type(ty).and_then(|t| { t.safe_canonical_type(ctx) }); @@ -278,7 +278,7 @@ impl ClangSubItemParser for Var { }; let mangling = cursor_mangling(ctx, &cursor); - let var = Var::new(name, mangling, ty.as_type_id_unchecked(), value, is_const); + let var = Var::new(name, mangling, ty, value, is_const); Ok(ParseResult::New(var, Some(cursor))) } diff --git a/src/parse.rs b/src/parse.rs index 5869f302bf..1a9278b300 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,7 +1,7 @@ //! Common traits and types related to parsing our IR from Clang cursors. use clang; -use ir::context::{BindgenContext, ItemId}; +use ir::context::{BindgenContext, ItemId, TypeId}; use ir::ty::TypeKind; /// Not so much an error in the traditional sense, but a control flow message @@ -55,7 +55,7 @@ pub trait ClangItemParser: Sized { location: clang::Cursor, parent: Option, ctx: &mut BindgenContext, - ) -> Result; + ) -> Result; /// Identical to `from_ty`, but use the given `id` as the `ItemId` for the /// newly parsed item. @@ -65,7 +65,7 @@ pub trait ClangItemParser: Sized { location: clang::Cursor, parent: Option, ctx: &mut BindgenContext, - ) -> Result; + ) -> Result; /// Parse this item from the given Clang type, or if we haven't resolved all /// the other items this one depends on, an unresolved reference. @@ -74,7 +74,7 @@ pub trait ClangItemParser: Sized { location: clang::Cursor, parent_id: Option, context: &mut BindgenContext, - ) -> ItemId; + ) -> TypeId; /// Identical to `from_ty_or_ref`, but use the given `potential_id` as the /// `ItemId` for the newly parsed item. @@ -84,19 +84,19 @@ pub trait ClangItemParser: Sized { location: clang::Cursor, parent_id: Option, context: &mut BindgenContext, - ) -> ItemId; + ) -> TypeId; /// Create a named template type. fn type_param( with_id: Option, location: clang::Cursor, ctx: &mut BindgenContext, - ) -> Option; + ) -> Option; /// Create a builtin type. fn builtin_type( kind: TypeKind, is_const: bool, context: &mut BindgenContext, - ) -> ItemId; + ) -> TypeId; } From c780d9475020345b39e5f1c287fe22efb181e626 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 17:46:35 -0700 Subject: [PATCH 14/25] Turn `CompInfo::inner_types` into TypeId --- src/ir/comp.rs | 13 +++++++------ src/ir/context.rs | 8 ++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/ir/comp.rs b/src/ir/comp.rs index c193acaba1..8dd49d1224 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -850,7 +850,7 @@ pub struct CompInfo { /// } /// /// static Foo::Bar const = {3}; - inner_types: Vec, + inner_types: Vec, /// Set of static constants declared inside this class. inner_vars: Vec, @@ -1155,6 +1155,8 @@ impl CompInfo { .expect("Inner ClassDecl"); assert_eq!(ctx.resolve_item(inner).parent_id(), potential_id); + let inner = inner.expect_type_id(ctx); + ci.inner_types.push(inner); // A declaration of an union or a struct without name could @@ -1163,8 +1165,7 @@ impl CompInfo { cur.kind() != CXCursor_EnumDecl { let ty = cur.cur_type(); let offset = cur.offset_of_field().ok(); - maybe_anonymous_struct_field = - Some((inner.as_type_id_unchecked(), ty, offset)); + maybe_anonymous_struct_field = Some((inner, ty, offset)); } } CXCursor_PackedAttr => { @@ -1328,7 +1329,7 @@ impl CompInfo { /// Get the set of types that were declared within this compound type /// (e.g. nested class definitions). - pub fn inner_types(&self) -> &[ItemId] { + pub fn inner_types(&self) -> &[TypeId] { &self.inner_types } @@ -1486,8 +1487,8 @@ impl Trace for CompInfo { tracer.visit_kind(p.into(), EdgeKind::TemplateParameterDefinition); } - for &ty in self.inner_types() { - tracer.visit_kind(ty, EdgeKind::InnerType); + for ty in self.inner_types() { + tracer.visit_kind(ty.into(), EdgeKind::InnerType); } for &var in self.inner_vars() { diff --git a/src/ir/context.rs b/src/ir/context.rs index a48b145f62..f83435c6b6 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -73,6 +73,14 @@ impl ItemId { } } + /// Convert this `ItemId` into a `TypeId`. + /// + /// If this `ItemId` does not point to a type, then panic. + pub fn expect_type_id(&self, ctx: &BindgenContext) -> TypeId { + self.as_type_id(ctx) + .expect("expect_type_id called with ItemId that doesn't point to a type") + } + /// Convert this `ItemId` into a `TypeId` without actually checking whether /// this id actually points to a `Type`. pub fn as_type_id_unchecked(&self) -> TypeId { From 9220ffe0b485f0e2b1d0d59f25e3242bbdd552f7 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 17:52:15 -0700 Subject: [PATCH 15/25] Replacement should use TypeId rather than ItemId --- src/ir/context.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ir/context.rs b/src/ir/context.rs index f83435c6b6..aa26892695 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -926,19 +926,19 @@ impl BindgenContext { // We set this just after parsing the annotation. It's // very unlikely, but this can happen. if self.items.get(replacement).is_some() { - replacements.push((*id, *replacement)); + replacements.push((id.expect_type_id(self), replacement.expect_type_id(self))); } } } } - for (id, replacement) in replacements { - debug!("Replacing {:?} with {:?}", id, replacement); + for (id, replacement_id) in replacements { + debug!("Replacing {:?} with {:?}", id, replacement_id); let new_parent = { - let item = self.items.get_mut(&id).unwrap(); + let item = self.items.get_mut(&id.into()).unwrap(); *item.kind_mut().as_type_mut().unwrap().kind_mut() = - TypeKind::ResolvedTypeRef(replacement.as_type_id_unchecked()); + TypeKind::ResolvedTypeRef(replacement_id); item.parent_id() }; @@ -947,7 +947,7 @@ impl BindgenContext { // // First, we'll make sure that its parent id is correct. - let old_parent = self.resolve_item(replacement).parent_id(); + let old_parent = self.resolve_item(replacement_id).parent_id(); if new_parent == old_parent { // Same parent and therefore also same containing // module. Nothing to do here. @@ -955,7 +955,7 @@ impl BindgenContext { } self.items - .get_mut(&replacement) + .get_mut(&replacement_id.into()) .unwrap() .set_parent_for_replacement(new_parent); @@ -970,7 +970,7 @@ impl BindgenContext { .find(|id| { let item = immut_self.resolve_item(*id); item.as_module().map_or(false, |m| { - m.children().contains(&replacement) + m.children().contains(&replacement_id.into()) }) }) }; @@ -997,7 +997,7 @@ impl BindgenContext { .as_module_mut() .unwrap() .children_mut() - .remove(&replacement); + .remove(&replacement_id.into()); self.items .get_mut(&new_module) @@ -1005,7 +1005,7 @@ impl BindgenContext { .as_module_mut() .unwrap() .children_mut() - .insert(replacement); + .insert(replacement_id.into()); } } From 2549d5eb98e13234fef5fd19500e0c51879d974c Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 18:03:44 -0700 Subject: [PATCH 16/25] Replace `as_type_id_unchecked` calls with checked calls where possible --- src/ir/context.rs | 19 +++++++++++-------- src/ir/function.rs | 6 +++++- src/ir/item.rs | 5 +++-- src/ir/ty.rs | 2 +- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/ir/context.rs b/src/ir/context.rs index aa26892695..cdc1dcebf3 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -67,7 +67,7 @@ impl ItemId { /// otherwise return `None`. pub fn as_type_id(&self, ctx: &BindgenContext) -> Option { if ctx.resolve_item(*self).kind().is_type() { - Some(self.as_type_id_unchecked()) + Some(TypeId(*self)) } else { None } @@ -1348,7 +1348,7 @@ impl BindgenContext { fn get_declaration_info_for_template_instantiation( &self, instantiation: &Cursor, - ) -> Option<(Cursor, TypeId, usize)> { + ) -> Option<(Cursor, ItemId, usize)> { instantiation .cur_type() .canonical_declaration(Some(instantiation)) @@ -1359,7 +1359,7 @@ impl BindgenContext { |num_params| { ( *canon_decl.cursor(), - template_decl_id, + template_decl_id.into(), num_params, ) }, @@ -1540,7 +1540,9 @@ impl BindgenContext { let sub_name = Some(template_decl_cursor.spelling()); let sub_inst = TemplateInstantiation::new( - template_decl_id, + // This isn't guaranteed to be a type that we've + // already finished parsing yet. + template_decl_id.as_type_id_unchecked(), sub_args, ); let sub_kind = @@ -2398,13 +2400,14 @@ impl ItemResolver { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct PartialType { decl: Cursor, - id: TypeId, + // Just an ItemId, and not a TypeId, because we haven't finished this type + // yet, so there's still time for things to go wrong. + id: ItemId, } impl PartialType { /// Construct a new `PartialType`. - pub fn new>(decl: Cursor, id: Id) -> PartialType { - let id = id.into().as_type_id_unchecked(); + pub fn new(decl: Cursor, id: ItemId) -> PartialType { // assert!(decl == decl.canonical()); PartialType { decl: decl, @@ -2419,7 +2422,7 @@ impl PartialType { /// The item ID allocated for this type. This is *NOT* a key for an entry in /// the context's item set yet! - pub fn id(&self) -> TypeId { + pub fn id(&self) -> ItemId { self.id } } diff --git a/src/ir/function.rs b/src/ir/function.rs index 990fbaff9d..ccdfc4f350 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -384,8 +384,12 @@ impl FunctionSig { if !is_static && !is_virtual { let class = Item::parse(cursor.semantic_parent(), None, ctx) .expect("Expected to parse the class"); + // The `class` most likely is not finished parsing yet, so use + // the unchecked variant. + let class = class.as_type_id_unchecked(); + let ptr = - Item::builtin_type(TypeKind::Pointer(class.as_type_id_unchecked()), is_const, ctx); + Item::builtin_type(TypeKind::Pointer(class), is_const, ctx); args.insert(0, (Some("this".into()), ptr)); } else if is_virtual { let void = Item::builtin_type(TypeKind::Void, false, ctx); diff --git a/src/ir/item.rs b/src/ir/item.rs index 825b9bc4d9..1e18cb7343 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -1472,7 +1472,8 @@ impl ClangItemParser for Item { ) { debug!("Avoiding recursion parsing type: {:?}", ty); - return Ok(partial.id()); + // Unchecked because we haven't finished this type yet. + return Ok(partial.id().as_type_id_unchecked()); } } @@ -1485,7 +1486,7 @@ impl ClangItemParser for Item { let result = Type::from_clang_ty(id, ty, location, parent_id, ctx); let relevant_parent_id = parent_id.unwrap_or(current_module); let ret = match result { - Ok(ParseResult::AlreadyResolved(ty)) => Ok(ty.as_type_id_unchecked()), + Ok(ParseResult::AlreadyResolved(ty)) => Ok(ty.expect_type_id(ctx)), Ok(ParseResult::New(item, declaration)) => { ctx.add_item( Item::new( diff --git a/src/ir/ty.rs b/src/ir/ty.rs index a5f3a69409..601dce6cba 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -397,7 +397,7 @@ impl AsTemplateParam for TypeKind { item: &Item, ) -> Option { match *self { - TypeKind::TypeParam => Some(item.id().as_type_id_unchecked()), + TypeKind::TypeParam => Some(item.id().expect_type_id(ctx)), TypeKind::ResolvedTypeRef(id) => id.as_template_param(ctx, &()), _ => None, } From c912f553a4cdb34b84f22f9634d2b3fb5bbb8090 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 18:19:55 -0700 Subject: [PATCH 17/25] Introduce ModuleId to strongly type IDs pointing at Modules --- src/codegen/mod.rs | 2 +- src/ir/context.rs | 90 ++++++++++++++++++++++++++++++++++------------ src/ir/item.rs | 22 ++++++------ src/ir/module.rs | 4 +-- src/ir/ty.rs | 6 ++-- 5 files changed, 84 insertions(+), 40 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index ce5054c982..f2b3a17bab 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -379,7 +379,7 @@ impl CodeGenerator for Module { } } - if item.id() == ctx.root_module() { + if item.id() == ctx.root_module().into() { if result.saw_bindgen_union { utils::prepend_union_types(ctx, &mut *result); } diff --git a/src/ir/context.rs b/src/ir/context.rs index cdc1dcebf3..24213ebc2d 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -30,7 +30,7 @@ use std::collections::btree_map::{self, BTreeMap}; use std::iter::IntoIterator; use std::mem; -/// A single identifier for an item. +/// An identifier for some kind of IR item. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ItemId(usize); @@ -39,6 +39,11 @@ pub struct ItemId(usize); #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct TypeId(ItemId); +/// An identifier for an `Item` whose `ItemKind` is known to be +/// `ItemKind::Module`. +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ModuleId(ItemId); + impl From for ItemId { fn from(tid: TypeId) -> ItemId { tid.0 @@ -51,6 +56,18 @@ impl<'a> From<&'a TypeId> for ItemId { } } +impl From for ItemId { + fn from(mid: ModuleId) -> ItemId { + mid.0 + } +} + +impl<'a> From<&'a ModuleId> for ItemId { + fn from(mid: &'a ModuleId) -> ItemId { + mid.0 + } +} + impl From for usize { fn from(id: ItemId) -> usize { id.0 @@ -86,6 +103,30 @@ impl ItemId { pub fn as_type_id_unchecked(&self) -> TypeId { TypeId(*self) } + + /// Convert this `ItemId` into a `ModuleId` if its associated item is a module, + /// otherwise return `None`. + pub fn as_module_id(&self, ctx: &BindgenContext) -> Option { + if ctx.resolve_item(*self).kind().is_module() { + Some(ModuleId(*self)) + } else { + None + } + } + + /// Convert this `ItemId` into a `ModuleId`. + /// + /// If this `ItemId` does not point to a module, then panic. + pub fn expect_module_id(&self, ctx: &BindgenContext) -> ModuleId { + self.as_module_id(ctx) + .expect("expect_module_id called with ItemId that doesn't point to a module") + } + + /// Convert this `ItemId` into a `ModuleId` without actually checking whether + /// this id actually points to a `Module`. + pub fn as_module_id_unchecked(&self) -> ModuleId { + ModuleId(*self) + } } impl CanDeriveDebug for T @@ -200,13 +241,13 @@ pub struct BindgenContext { type_params: HashMap, /// A cursor to module map. Similar reason than above. - modules: HashMap, + modules: HashMap, /// The root module, this is guaranteed to be an item of kind Module. - root_module: ItemId, + root_module: ModuleId, /// Current module being traversed. - current_module: ItemId, + current_module: ModuleId, /// A HashMap keyed on a type definition, and whose value is the parent id /// of the declaration. @@ -449,14 +490,16 @@ impl BindgenContext { effective_target == "i686-pc-win32"; let root_module = Self::build_root_module(ItemId(0)); + let root_module_id = root_module.id().as_module_id_unchecked(); + let mut me = BindgenContext { items: Default::default(), types: Default::default(), type_params: Default::default(), modules: Default::default(), next_item_id: ItemId(1), - root_module: root_module.id(), - current_module: root_module.id(), + root_module: root_module_id, + current_module: root_module_id, semantic_parents: Default::default(), currently_parsed_types: vec![], parsed_macros: Default::default(), @@ -551,7 +594,7 @@ impl BindgenContext { let is_template_instantiation = is_type && item.expect_type().is_template_instantiation(); - if item.id() != self.root_module { + if item.id() != self.root_module.into() { self.add_item_to_module(&item); } @@ -615,7 +658,7 @@ impl BindgenContext { /// codegen'd, even if its parent is not whitelisted. See issue #769 for /// details. fn add_item_to_module(&mut self, item: &Item) { - assert!(item.id() != self.root_module); + assert!(item.id() != self.root_module.into()); assert!(!self.items.contains_key(&item.id())); if let Some(parent) = self.items.get_mut(&item.parent_id()) { @@ -638,7 +681,7 @@ impl BindgenContext { ); self.items - .get_mut(&self.current_module) + .get_mut(&self.current_module.into()) .expect("Should always have an item for self.current_module") .as_module_mut() .expect("self.current_module should always be a module") @@ -966,7 +1009,7 @@ impl BindgenContext { let immut_self = &*self; old_parent .ancestors(immut_self) - .chain(Some(immut_self.root_module)) + .chain(Some(immut_self.root_module.into())) .find(|id| { let item = immut_self.resolve_item(*id); item.as_module().map_or(false, |m| { @@ -984,7 +1027,7 @@ impl BindgenContext { immut_self.resolve_item(*id).is_module() }) }; - let new_module = new_module.unwrap_or(self.root_module); + let new_module = new_module.unwrap_or(self.root_module.into()); if new_module == old_module { // Already in the correct module. @@ -1091,7 +1134,7 @@ impl BindgenContext { assert!(self.current_module == self.root_module); for (&id, _item) in self.items() { - if id == self.root_module { + if id == self.root_module.into() { continue; } @@ -1102,7 +1145,7 @@ impl BindgenContext { .through_type_aliases() .resolve(self) .id(); - id.ancestors(self).chain(Some(self.root_module)).any( + id.ancestors(self).chain(Some(self.root_module.into())).any( |ancestor| { debug!( "Checking if {:?} is a child of {:?}", @@ -1271,7 +1314,7 @@ impl BindgenContext { } /// Get the root module. - pub fn root_module(&self) -> ItemId { + pub fn root_module(&self) -> ModuleId { self.root_module } @@ -1309,7 +1352,7 @@ impl BindgenContext { } /// Get the current module. - pub fn current_module(&self) -> ItemId { + pub fn current_module(&self) -> ModuleId { self.current_module } @@ -1561,7 +1604,7 @@ impl BindgenContext { sub_id, None, None, - self.current_module, + self.current_module.into(), ItemKind::Type(sub_ty), ); @@ -1625,7 +1668,7 @@ impl BindgenContext { with_id, None, None, - self.current_module, + self.current_module.into(), ItemKind::Type(ty), ); @@ -1745,7 +1788,7 @@ impl BindgenContext { with_id, None, None, - parent_id.unwrap_or(self.current_module), + parent_id.unwrap_or(self.current_module.into()), ItemKind::Type(ty), ); self.add_builtin_item(item); @@ -1809,7 +1852,7 @@ impl BindgenContext { let ty = Type::new(Some(spelling), layout, type_kind, is_const); let id = self.next_item_id(); let item = - Item::new(id, None, None, self.root_module, ItemKind::Type(ty)); + Item::new(id, None, None, self.root_module.into(), ItemKind::Type(ty)); self.add_builtin_item(item); Some(id.as_type_id_unchecked()) } @@ -1970,7 +2013,7 @@ impl BindgenContext { /// Given a CXCursor_Namespace cursor, return the item id of the /// corresponding module, or create one on the fly. - pub fn module(&mut self, cursor: clang::Cursor) -> ItemId { + pub fn module(&mut self, cursor: clang::Cursor) -> ModuleId { use clang_sys::*; assert_eq!(cursor.kind(), CXCursor_Namespace, "Be a nice person"); let cursor = cursor.canonical(); @@ -1986,11 +2029,12 @@ impl BindgenContext { module_id, None, None, - self.current_module, + self.current_module.into(), ItemKind::Module(module), ); - self.modules.insert(cursor, module.id()); + let module_id = module.id().as_module_id_unchecked(); + self.modules.insert(cursor, module_id); self.add_item(module, None, None); @@ -1999,7 +2043,7 @@ impl BindgenContext { /// Start traversing the module with the given `module_id`, invoke the /// callback `cb`, and then return to traversing the original module. - pub fn with_module(&mut self, module_id: ItemId, cb: F) + pub fn with_module(&mut self, module_id: ModuleId, cb: F) where F: FnOnce(&mut Self), { diff --git a/src/ir/item.rs b/src/ir/item.rs index 1e18cb7343..2b137584a0 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -465,7 +465,7 @@ impl Item { ) -> TypeId { let ty = Opaque::from_clang_ty(ty); let kind = ItemKind::Type(ty); - let parent = ctx.root_module(); + let parent = ctx.root_module().into(); ctx.add_item(Item::new(with_id, None, None, parent, kind), None, None); with_id.as_type_id_unchecked() } @@ -577,7 +577,7 @@ impl Item { // FIXME: Workaround for some types falling behind when parsing weird // stl classes, for example. if ctx.options().enable_cxx_namespaces && self.kind().is_module() && - self.id() != ctx.root_module() + self.id() != ctx.root_module().into() { return false; } @@ -589,7 +589,7 @@ impl Item { None => return false, }; - if parent_item.id() == ctx.root_module() { + if parent_item.id() == ctx.root_module().into() { return true; } else if ctx.options().enable_cxx_namespaces || !parent_item.kind().is_module() @@ -834,7 +834,7 @@ impl Item { let mut names: Vec<_> = target .parent_id() .ancestors(ctx) - .filter(|id| *id != ctx.root_module()) + .filter(|id| *id != ctx.root_module().into()) .take_while(|id| { // Stop iterating ancestors once we reach a non-inline namespace // when opt.within_namespaces is set. @@ -1162,7 +1162,7 @@ impl ClangItemParser for Item { let ty = Type::new(None, None, kind, is_const); let id = ctx.next_item_id(); - let module = ctx.root_module(); + let module = ctx.root_module().into(); ctx.add_item( Item::new(id, None, None, module, ItemKind::Type(ty)), None, @@ -1189,7 +1189,7 @@ impl ClangItemParser for Item { let comment = cursor.raw_comment(); let annotations = Annotations::new(&cursor); - let current_module = ctx.current_module(); + let current_module = ctx.current_module().into(); let relevant_parent_id = parent_id.unwrap_or(current_module); macro_rules! try_parse { @@ -1246,7 +1246,7 @@ impl ClangItemParser for Item { } ctx.known_semantic_parent(definition) .or(parent_id) - .unwrap_or(ctx.current_module()) + .unwrap_or(ctx.current_module().into()) } None => relevant_parent_id, }; @@ -1368,7 +1368,7 @@ impl ClangItemParser for Item { potential_id, None, None, - parent_id.unwrap_or(current_module), + parent_id.unwrap_or(current_module.into()), ItemKind::Type(Type::new(None, None, kind, is_const)), ), Some(clang::Cursor::null()), @@ -1477,7 +1477,7 @@ impl ClangItemParser for Item { } } - let current_module = ctx.current_module(); + let current_module = ctx.current_module().into(); let partial_ty = PartialType::new(declaration_to_look_for, id); if valid_decl { ctx.begin_parsing(partial_ty); @@ -1700,7 +1700,7 @@ impl ClangItemParser for Item { // referenced with namespace prefixes, and they can't inherit anything // from their parent either, so it is simplest to just hang them off // something we know will always exist. - let parent = ctx.root_module(); + let parent = ctx.root_module().into(); if let Some(id) = ctx.get_type_param(&definition) { if let Some(with_id) = with_id { @@ -1786,7 +1786,7 @@ impl ItemCanonicalPath for Item { let target = ctx.resolve_item(self.name_target(ctx)); let mut path: Vec<_> = target .ancestors(ctx) - .chain(iter::once(ctx.root_module())) + .chain(iter::once(ctx.root_module().into())) .map(|id| ctx.resolve_item(id)) .filter(|item| { item.id() == target.id() || diff --git a/src/ir/module.rs b/src/ir/module.rs index c66623dd6b..af46d4acae 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -83,11 +83,11 @@ impl ClangSubItemParser for Module { let module_id = ctx.module(cursor); ctx.with_module(module_id, |ctx| { cursor.visit( - |cursor| parse_one(ctx, cursor, Some(module_id)), + |cursor| parse_one(ctx, cursor, Some(module_id.into())), ) }); - Ok(ParseResult::AlreadyResolved(module_id)) + Ok(ParseResult::AlreadyResolved(module_id.into())) } _ => Err(ParseError::Continue), } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 601dce6cba..5aef39a2b0 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -702,16 +702,16 @@ impl Type { TypeKind::Comp(ref ci) => ci.is_unsized(ctx, id), TypeKind::Opaque => self.layout.map_or(true, |l| l.size == 0), TypeKind::Array(inner, size) => { - size == 0 || ctx.resolve_type(inner).is_unsized(ctx, &inner.into()) + size == 0 || ctx.resolve_type(inner).is_unsized(ctx, inner) } TypeKind::ResolvedTypeRef(inner) | TypeKind::Alias(inner) | TypeKind::TemplateAlias(inner, _) => { - ctx.resolve_type(inner).is_unsized(ctx, &inner.into()) + ctx.resolve_type(inner).is_unsized(ctx, inner) } TypeKind::TemplateInstantiation(ref inst) => { let definition = inst.template_definition(); - ctx.resolve_type(definition).is_unsized(ctx, &definition.into()) + ctx.resolve_type(definition).is_unsized(ctx, definition) } TypeKind::TypeParam | TypeKind::Int(..) | From 9b294d3d8b6ae3332d111d2f29b16bac877a8fa8 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 18:38:46 -0700 Subject: [PATCH 18/25] Put newtype-of-ItemId boilerplate behind a macro --- src/ir/context.rs | 170 +++++++++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 79 deletions(-) diff --git a/src/ir/context.rs b/src/ir/context.rs index 24213ebc2d..07731dde3e 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -34,38 +34,105 @@ use std::mem; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ItemId(usize); -/// An identifier for an `Item` whose `ItemKind` is known to be -/// `ItemKind::Type`. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct TypeId(ItemId); +macro_rules! item_id_newtype { + ( + $( #[$attr:meta] )* + pub struct $name:ident(ItemId) + where + $( #[$checked_attr:meta] )* + checked = $checked:ident with $check_method:ident, + $( #[$expected_attr:meta] )* + expected = $expected:ident, + $( #[$unchecked_attr:meta] )* + unchecked = $unchecked:ident; + ) => { + $( #[$attr] )* + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct $name(ItemId); + + impl $name { + /// Create an `ItemResolver` from this id. + pub fn into_resolver(self) -> ItemResolver { + let id: ItemId = self.into(); + id.into() + } + } -/// An identifier for an `Item` whose `ItemKind` is known to be -/// `ItemKind::Module`. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct ModuleId(ItemId); + impl From<$name> for ItemId { + fn from(id: $name) -> ItemId { + id.0 + } + } -impl From for ItemId { - fn from(tid: TypeId) -> ItemId { - tid.0 - } -} + impl<'a> From<&'a $name> for ItemId { + fn from(id: &'a $name) -> ItemId { + id.0 + } + } + + impl ItemId { + $( #[$checked_attr] )* + pub fn $checked(&self, ctx: &BindgenContext) -> Option<$name> { + if ctx.resolve_item(*self).kind().$check_method() { + Some($name(*self)) + } else { + None + } + } + + $( #[$expected_attr] )* + pub fn $expected(&self, ctx: &BindgenContext) -> $name { + self.$checked(ctx) + .expect(concat!( + stringify!($expected), + " called with ItemId that points to the wrong ItemKind" + )) + } -impl<'a> From<&'a TypeId> for ItemId { - fn from(tid: &'a TypeId) -> ItemId { - tid.0 + $( #[$unchecked_attr] )* + pub fn $unchecked(&self) -> $name { + $name(*self) + } + } } } -impl From for ItemId { - fn from(mid: ModuleId) -> ItemId { - mid.0 - } +item_id_newtype! { + /// An identifier for an `Item` whose `ItemKind` is known to be + /// `ItemKind::Type`. + pub struct TypeId(ItemId) + where + /// Convert this `ItemId` into a `TypeId` if its associated item is a type, + /// otherwise return `None`. + checked = as_type_id with is_type, + + /// Convert this `ItemId` into a `TypeId`. + /// + /// If this `ItemId` does not point to a type, then panic. + expected = expect_type_id, + + /// Convert this `ItemId` into a `TypeId` without actually checking whether + /// this id actually points to a `Type`. + unchecked = as_type_id_unchecked; } -impl<'a> From<&'a ModuleId> for ItemId { - fn from(mid: &'a ModuleId) -> ItemId { - mid.0 - } +item_id_newtype! { + /// An identifier for an `Item` whose `ItemKind` is known to be + /// `ItemKind::Module`. + pub struct ModuleId(ItemId) + where + /// Convert this `ItemId` into a `ModuleId` if its associated item is a + /// module, otherwise return `None`. + checked = as_module_id with is_module, + + /// Convert this `ItemId` into a `ModuleId`. + /// + /// If this `ItemId` does not point to a module, then panic. + expected = expect_module_id, + + /// Convert this `ItemId` into a `ModuleId` without actually checking + /// whether this id actually points to a `Module`. + unchecked = as_module_id_unchecked; } impl From for usize { @@ -79,54 +146,6 @@ impl ItemId { pub fn as_usize(&self) -> usize { (*self).into() } - - /// Convert this `ItemId` into a `TypeId` if its associated item is a type, - /// otherwise return `None`. - pub fn as_type_id(&self, ctx: &BindgenContext) -> Option { - if ctx.resolve_item(*self).kind().is_type() { - Some(TypeId(*self)) - } else { - None - } - } - - /// Convert this `ItemId` into a `TypeId`. - /// - /// If this `ItemId` does not point to a type, then panic. - pub fn expect_type_id(&self, ctx: &BindgenContext) -> TypeId { - self.as_type_id(ctx) - .expect("expect_type_id called with ItemId that doesn't point to a type") - } - - /// Convert this `ItemId` into a `TypeId` without actually checking whether - /// this id actually points to a `Type`. - pub fn as_type_id_unchecked(&self) -> TypeId { - TypeId(*self) - } - - /// Convert this `ItemId` into a `ModuleId` if its associated item is a module, - /// otherwise return `None`. - pub fn as_module_id(&self, ctx: &BindgenContext) -> Option { - if ctx.resolve_item(*self).kind().is_module() { - Some(ModuleId(*self)) - } else { - None - } - } - - /// Convert this `ItemId` into a `ModuleId`. - /// - /// If this `ItemId` does not point to a module, then panic. - pub fn expect_module_id(&self, ctx: &BindgenContext) -> ModuleId { - self.as_module_id(ctx) - .expect("expect_module_id called with ItemId that doesn't point to a module") - } - - /// Convert this `ItemId` into a `ModuleId` without actually checking whether - /// this id actually points to a `Module`. - pub fn as_module_id_unchecked(&self) -> ModuleId { - ModuleId(*self) - } } impl CanDeriveDebug for T @@ -2375,13 +2394,6 @@ impl ItemId { } } -impl TypeId { - pub fn into_resolver(self) -> ItemResolver { - let id: ItemId = self.into(); - id.into() - } -} - impl From for ItemResolver where T: Into From edee094d3c3662f8c045c19e9705d32f7b652bb1 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Fri, 29 Sep 2017 18:41:38 -0700 Subject: [PATCH 19/25] Introduce VarId for ids pointing to Var --- src/ir/context.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/ir/context.rs b/src/ir/context.rs index 07731dde3e..5ebcfc28af 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -135,6 +135,25 @@ item_id_newtype! { unchecked = as_module_id_unchecked; } +item_id_newtype! { + /// An identifier for an `Item` whose `ItemKind` is known to be + /// `ItemKind::Var`. + pub struct VarId(ItemId) + where + /// Convert this `ItemId` into a `VarId` if its associated item is a var, + /// otherwise return `None`. + checked = as_var_id with is_var, + + /// Convert this `ItemId` into a `VarId`. + /// + /// If this `ItemId` does not point to a var, then panic. + expected = expect_var_id, + + /// Convert this `ItemId` into a `VarId` without actually checking whether + /// this id actually points to a `Var`. + unchecked = as_var_id_unchecked; +} + impl From for usize { fn from(id: ItemId) -> usize { id.0 From 45db21bfed19f318290c9c32edf42ba4a0a26ada Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 2 Oct 2017 11:54:49 -0700 Subject: [PATCH 20/25] Make `CompInfo::inner_vars` use `VarId` instead of `ItemId` --- src/ir/comp.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 8dd49d1224..3d09363ccb 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -2,7 +2,7 @@ use super::analysis::HasVtable; use super::annotations::Annotations; -use super::context::{BindgenContext, ItemId, TypeId}; +use super::context::{BindgenContext, ItemId, TypeId, VarId}; use super::dot::DotAttributes; use super::item::{IsOpaque, Item}; use super::layout::Layout; @@ -853,7 +853,7 @@ pub struct CompInfo { inner_types: Vec, /// Set of static constants declared inside this class. - inner_vars: Vec, + inner_vars: Vec, /// Whether this type should generate an vtable (TODO: Should be able to /// look at the virtual methods and ditch this field). @@ -1276,7 +1276,7 @@ impl CompInfo { if let Ok(item) = Item::parse(cur, Some(potential_id), ctx) { - ci.inner_vars.push(item); + ci.inner_vars.push(item.as_var_id_unchecked()); } } // Intentionally not handled @@ -1334,7 +1334,7 @@ impl CompInfo { } /// Get the set of static variables declared within this compound type. - pub fn inner_vars(&self) -> &[ItemId] { + pub fn inner_vars(&self) -> &[VarId] { &self.inner_vars } @@ -1492,7 +1492,7 @@ impl Trace for CompInfo { } for &var in self.inner_vars() { - tracer.visit_kind(var, EdgeKind::InnerVar); + tracer.visit_kind(var.into(), EdgeKind::InnerVar); } for method in self.methods() { From 3ef31e851e530d38f867c9063200576dee4494b0 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 2 Oct 2017 11:57:29 -0700 Subject: [PATCH 21/25] Introduce the `FunctionId` newtype for ids pointing to functions --- src/ir/context.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/ir/context.rs b/src/ir/context.rs index 5ebcfc28af..f9efbf054c 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -154,6 +154,25 @@ item_id_newtype! { unchecked = as_var_id_unchecked; } +item_id_newtype! { + /// An identifier for an `Item` whose `ItemKind` is known to be + /// `ItemKind::Function`. + pub struct FunctionId(ItemId) + where + /// Convert this `ItemId` into a `FunctionId` if its associated item is a function, + /// otherwise return `None`. + checked = as_function_id with is_function, + + /// Convert this `ItemId` into a `FunctionId`. + /// + /// If this `ItemId` does not point to a function, then panic. + expected = expect_function_id, + + /// Convert this `ItemId` into a `FunctionId` without actually checking whether + /// this id actually points to a `Function`. + unchecked = as_function_id_unchecked; +} + impl From for usize { fn from(id: ItemId) -> usize { id.0 From 3495d03e98bfe623f83083d1788e08f73d876a59 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 2 Oct 2017 12:20:53 -0700 Subject: [PATCH 22/25] Make methods/constructors/destructors use FunctionId And also allow ID comparison across ID types, as this makes implementing the above much easier. --- src/codegen/mod.rs | 2 +- src/ir/analysis/template_params.rs | 2 +- src/ir/comp.rs | 28 +++++++++++++++------------- src/ir/context.rs | 30 +++++++++++++++++++++++++----- src/ir/item.rs | 6 +++--- 5 files changed, 45 insertions(+), 23 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index f2b3a17bab..ce5054c982 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -379,7 +379,7 @@ impl CodeGenerator for Module { } } - if item.id() == ctx.root_module().into() { + if item.id() == ctx.root_module() { if result.saw_bindgen_union { utils::prepend_union_types(ctx, &mut *result); } diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs index 24ab4f2626..00504aa40e 100644 --- a/src/ir/analysis/template_params.rs +++ b/src/ir/analysis/template_params.rs @@ -277,7 +277,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> { let params = decl.self_template_params(self.ctx).unwrap_or(vec![]); - debug_assert!(this_id != instantiation.template_definition().into()); + debug_assert!(this_id != instantiation.template_definition()); let used_by_def = self.used .get(&instantiation.template_definition().into()) .expect("Should have a used entry for instantiation's template definition") diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 3d09363ccb..fa1370684b 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -2,7 +2,7 @@ use super::analysis::HasVtable; use super::annotations::Annotations; -use super::context::{BindgenContext, ItemId, TypeId, VarId}; +use super::context::{BindgenContext, FunctionId, ItemId, TypeId, VarId}; use super::dot::DotAttributes; use super::item::{IsOpaque, Item}; use super::layout::Layout; @@ -53,13 +53,13 @@ pub struct Method { /// item, but a `Function` one. /// /// This is tricky and probably this field should be renamed. - signature: ItemId, + signature: FunctionId, is_const: bool, } impl Method { /// Construct a new `Method`. - pub fn new(kind: MethodKind, signature: ItemId, is_const: bool) -> Self { + pub fn new(kind: MethodKind, signature: FunctionId, is_const: bool) -> Self { Method { kind: kind, signature: signature, @@ -94,8 +94,8 @@ impl Method { self.kind == MethodKind::Static } - /// Get the `ItemId` for the `Function` signature for this method. - pub fn signature(&self) -> ItemId { + /// Get the id for the `Function` signature for this method. + pub fn signature(&self) -> FunctionId { self.signature } @@ -831,11 +831,11 @@ pub struct CompInfo { methods: Vec, /// The different constructors this struct or class contains. - constructors: Vec, + constructors: Vec, /// The destructor of this type. The bool represents whether this destructor /// is virtual. - destructor: Option<(bool, ItemId)>, + destructor: Option<(bool, FunctionId)>, /// Vector of classes this one inherits from. base_members: Vec, @@ -984,12 +984,12 @@ impl CompInfo { } /// Get this type's set of constructors. - pub fn constructors(&self) -> &[ItemId] { + pub fn constructors(&self) -> &[FunctionId] { &self.constructors } /// Get this type's destructor. - pub fn destructor(&self) -> Option<(bool, ItemId)> { + pub fn destructor(&self) -> Option<(bool, FunctionId)> { self.destructor } @@ -1233,6 +1233,8 @@ impl CompInfo { _ => return CXChildVisit_Continue, }; + let signature = signature.expect_function_id(ctx); + match cur.kind() { CXCursor_Constructor => { ci.constructors.push(signature); @@ -1497,14 +1499,14 @@ impl Trace for CompInfo { for method in self.methods() { if method.is_destructor() { - tracer.visit_kind(method.signature, EdgeKind::Destructor); + tracer.visit_kind(method.signature.into(), EdgeKind::Destructor); } else { - tracer.visit_kind(method.signature, EdgeKind::Method); + tracer.visit_kind(method.signature.into(), EdgeKind::Method); } } - for &ctor in self.constructors() { - tracer.visit_kind(ctor, EdgeKind::Constructor); + for ctor in self.constructors() { + tracer.visit_kind(ctor.into(), EdgeKind::Constructor); } // Base members and fields are not generated for opaque types (but all diff --git a/src/ir/context.rs b/src/ir/context.rs index f9efbf054c..3dfef1de50 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -31,7 +31,7 @@ use std::iter::IntoIterator; use std::mem; /// An identifier for some kind of IR item. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Debug, Copy, Clone, Eq, PartialOrd, Ord, Hash)] pub struct ItemId(usize); macro_rules! item_id_newtype { @@ -47,7 +47,7 @@ macro_rules! item_id_newtype { unchecked = $unchecked:ident; ) => { $( #[$attr] )* - #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] + #[derive(Debug, Copy, Clone, Eq, PartialOrd, Ord, Hash)] pub struct $name(ItemId); impl $name { @@ -58,6 +58,16 @@ macro_rules! item_id_newtype { } } + impl ::std::cmp::PartialEq for $name + where + T: Copy + Into + { + fn eq(&self, rhs: &T) -> bool { + let rhs: ItemId = (*rhs).into(); + self.0 == rhs + } + } + impl From<$name> for ItemId { fn from(id: $name) -> ItemId { id.0 @@ -186,6 +196,16 @@ impl ItemId { } } +impl ::std::cmp::PartialEq for ItemId +where + T: Copy + Into +{ + fn eq(&self, rhs: &T) -> bool { + let rhs: ItemId = (*rhs).into(); + self.0 == rhs.0 + } +} + impl CanDeriveDebug for T where T: Copy + Into @@ -651,7 +671,7 @@ impl BindgenContext { let is_template_instantiation = is_type && item.expect_type().is_template_instantiation(); - if item.id() != self.root_module.into() { + if item.id() != self.root_module { self.add_item_to_module(&item); } @@ -715,7 +735,7 @@ impl BindgenContext { /// codegen'd, even if its parent is not whitelisted. See issue #769 for /// details. fn add_item_to_module(&mut self, item: &Item) { - assert!(item.id() != self.root_module.into()); + assert!(item.id() != self.root_module); assert!(!self.items.contains_key(&item.id())); if let Some(parent) = self.items.get_mut(&item.parent_id()) { @@ -1191,7 +1211,7 @@ impl BindgenContext { assert!(self.current_module == self.root_module); for (&id, _item) in self.items() { - if id == self.root_module.into() { + if id == self.root_module { continue; } diff --git a/src/ir/item.rs b/src/ir/item.rs index 2b137584a0..3a4c49d46c 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -577,7 +577,7 @@ impl Item { // FIXME: Workaround for some types falling behind when parsing weird // stl classes, for example. if ctx.options().enable_cxx_namespaces && self.kind().is_module() && - self.id() != ctx.root_module().into() + self.id() != ctx.root_module() { return false; } @@ -589,7 +589,7 @@ impl Item { None => return false, }; - if parent_item.id() == ctx.root_module().into() { + if parent_item.id() == ctx.root_module() { return true; } else if ctx.options().enable_cxx_namespaces || !parent_item.kind().is_module() @@ -834,7 +834,7 @@ impl Item { let mut names: Vec<_> = target .parent_id() .ancestors(ctx) - .filter(|id| *id != ctx.root_module().into()) + .filter(|id| *id != ctx.root_module()) .take_while(|id| { // Stop iterating ancestors once we reach a non-inline namespace // when opt.within_namespaces is set. From a8c34ed60da2539f9e784c039110d29c7b34fd89 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 2 Oct 2017 13:16:45 -0700 Subject: [PATCH 23/25] Tighten up `is_unsized` and `has_vtable` checks to operated on TypeId --- src/codegen/mod.rs | 4 ++-- src/ir/comp.rs | 4 ++-- src/ir/context.rs | 2 +- src/ir/item.rs | 8 ++++++-- src/ir/ty.rs | 3 +-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index ce5054c982..264b701b89 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1626,7 +1626,7 @@ impl CodeGenerator for CompInfo { warn!("Opaque type without layout! Expect dragons!"); } } - } else if !is_union && !self.is_unsized(ctx, item.id()) { + } else if !is_union && !self.is_unsized(ctx, item.id().expect_type_id(ctx)) { if let Some(padding_field) = layout.and_then(|layout| struct_layout.pad_struct(layout)) { @@ -1650,7 +1650,7 @@ impl CodeGenerator for CompInfo { // // NOTE: This check is conveniently here to avoid the dummy fields we // may add for unused template parameters. - if self.is_unsized(ctx, item.id()) { + if self.is_unsized(ctx, item.id().expect_type_id(ctx)) { let has_address = if is_opaque { // Generate the address field if it's an opaque type and // couldn't determine the layout of the blob. diff --git a/src/ir/comp.rs b/src/ir/comp.rs index fa1370684b..caa02243c7 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -911,8 +911,8 @@ impl CompInfo { } /// Is this compound type unsized? - pub fn is_unsized>(&self, ctx: &BindgenContext, id: Id) -> bool { - !ctx.lookup_item_id_has_vtable(id.into()) && self.fields().is_empty() && + pub fn is_unsized(&self, ctx: &BindgenContext, id: TypeId) -> bool { + !ctx.lookup_item_id_has_vtable(id) && self.fields().is_empty() && self.base_members.iter().all(|base| { ctx.resolve_type(base.ty).canonical_type(ctx).is_unsized( ctx, diff --git a/src/ir/context.rs b/src/ir/context.rs index 3dfef1de50..1c85e73824 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1253,7 +1253,7 @@ impl BindgenContext { } /// Look up whether the item with `id` has vtable or not. - pub fn lookup_item_id_has_vtable>(&self, id: Id) -> bool { + pub fn lookup_item_id_has_vtable(&self, id: TypeId) -> bool { assert!( self.in_codegen_phase(), "We only compute vtables when we enter codegen" diff --git a/src/ir/item.rs b/src/ir/item.rs index 3a4c49d46c..31d420806b 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -999,13 +999,17 @@ where T: Copy + Into { fn has_vtable(&self, ctx: &BindgenContext) -> bool { - ctx.lookup_item_id_has_vtable(*self) + let id: ItemId = (*self).into(); + id.as_type_id(ctx) + .map_or(false, |id| ctx.lookup_item_id_has_vtable(id)) } } impl HasVtable for Item { fn has_vtable(&self, ctx: &BindgenContext) -> bool { - ctx.lookup_item_id_has_vtable(self.id()) + self.id() + .as_type_id(ctx) + .map_or(false, |id| ctx.lookup_item_id_has_vtable(id)) } } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 5aef39a2b0..4555534451 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -693,10 +693,9 @@ impl Type { /// derive whether we should generate a dummy `_address` field for structs, /// to comply to the C and C++ layouts, that specify that every type needs /// to be addressable. - pub fn is_unsized>(&self, ctx: &BindgenContext, id: Id) -> bool { + pub fn is_unsized(&self, ctx: &BindgenContext, id: TypeId) -> bool { debug_assert!(ctx.in_codegen_phase(), "Not yet"); - let id = id.into(); match self.kind { TypeKind::Void => true, TypeKind::Comp(ref ci) => ci.is_unsized(ctx, id), From 3b8278678afdc940f39c137e709b06c293145d83 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 2 Oct 2017 13:20:34 -0700 Subject: [PATCH 24/25] Make `has_destructor` checks operate on TypeId --- src/ir/analysis/derive_copy.rs | 2 +- src/ir/context.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index e4241b5b5e..ba8ad500ac 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -224,7 +224,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { // NOTE: Take into account that while unions in C and C++ are copied by // default, the may have an explicit destructor in C++, so we can't // defer this check just for the union case. - if self.ctx.lookup_item_id_has_destructor(&id) { + if self.ctx.lookup_item_id_has_destructor(id.expect_type_id(self.ctx)) { trace!(" comp has destructor which cannot derive copy"); return self.insert(id); } diff --git a/src/ir/context.rs b/src/ir/context.rs index 1c85e73824..0edf10be3c 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1272,13 +1272,13 @@ impl BindgenContext { } /// Look up whether the item with `id` has a destructor. - pub fn lookup_item_id_has_destructor(&self, id: &ItemId) -> bool { + pub fn lookup_item_id_has_destructor(&self, id: TypeId) -> bool { assert!( self.in_codegen_phase(), "We only compute destructors when we enter codegen" ); - self.have_destructor.as_ref().unwrap().contains(id) + self.have_destructor.as_ref().unwrap().contains(&id.into()) } fn find_used_template_parameters(&mut self) { From 5f3bf1f0230d753edf198d9d4e1266b3c0756e2d Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Mon, 2 Oct 2017 13:29:59 -0700 Subject: [PATCH 25/25] s/lookup_item_id/lookup/ in method names Its not just item ids now, and that name was pretty long... --- src/ir/analysis/derive_copy.rs | 2 +- src/ir/comp.rs | 2 +- src/ir/context.rs | 40 +++++++++++++++++----------------- src/ir/item.rs | 32 +++++++++++++-------------- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index ba8ad500ac..ba40141ee9 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -224,7 +224,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { // NOTE: Take into account that while unions in C and C++ are copied by // default, the may have an explicit destructor in C++, so we can't // defer this check just for the union case. - if self.ctx.lookup_item_id_has_destructor(id.expect_type_id(self.ctx)) { + if self.ctx.lookup_has_destructor(id.expect_type_id(self.ctx)) { trace!(" comp has destructor which cannot derive copy"); return self.insert(id); } diff --git a/src/ir/comp.rs b/src/ir/comp.rs index caa02243c7..c1dd369bca 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -912,7 +912,7 @@ impl CompInfo { /// Is this compound type unsized? pub fn is_unsized(&self, ctx: &BindgenContext, id: TypeId) -> bool { - !ctx.lookup_item_id_has_vtable(id) && self.fields().is_empty() && + !ctx.lookup_has_vtable(id) && self.fields().is_empty() && self.base_members.iter().all(|base| { ctx.resolve_type(base.ty).canonical_type(ctx).is_unsized( ctx, diff --git a/src/ir/context.rs b/src/ir/context.rs index 0edf10be3c..37b71ba1c9 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -211,7 +211,7 @@ where T: Copy + Into { fn can_derive_debug(&self, ctx: &BindgenContext) -> bool { - ctx.options().derive_debug && ctx.lookup_item_id_can_derive_debug(*self) + ctx.options().derive_debug && ctx.lookup_can_derive_debug(*self) } } @@ -221,7 +221,7 @@ where { fn can_derive_default(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_default && - ctx.lookup_item_id_can_derive_default(*self) + ctx.lookup_can_derive_default(*self) } } @@ -230,7 +230,7 @@ where T: Copy + Into { fn can_derive_copy(&self, ctx: &BindgenContext) -> bool { - ctx.lookup_item_id_can_derive_copy(*self) + ctx.lookup_can_derive_copy(*self) } } @@ -239,7 +239,7 @@ where T: Copy + Into { fn can_derive_hash(&self, ctx: &BindgenContext) -> bool { - ctx.options().derive_hash && ctx.lookup_item_id_can_derive_hash(*self) + ctx.options().derive_hash && ctx.lookup_can_derive_hash(*self) } } @@ -249,7 +249,7 @@ where { fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_partialord && - ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) + ctx.lookup_can_derive_partialeq_or_partialord(*self) } } @@ -259,7 +259,7 @@ where { fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_partialeq && - ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) + ctx.lookup_can_derive_partialeq_or_partialord(*self) } } @@ -269,8 +269,8 @@ where { fn can_derive_eq(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_eq && - ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) && - !ctx.lookup_item_id_has_float(*self) + ctx.lookup_can_derive_partialeq_or_partialord(*self) && + !ctx.lookup_has_float(*self) } } @@ -280,8 +280,8 @@ where { fn can_derive_ord(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_ord && - ctx.lookup_item_id_can_derive_partialeq_or_partialord(*self) && - !ctx.lookup_item_id_has_float(*self) + ctx.lookup_can_derive_partialeq_or_partialord(*self) && + !ctx.lookup_has_float(*self) } } @@ -1253,7 +1253,7 @@ impl BindgenContext { } /// Look up whether the item with `id` has vtable or not. - pub fn lookup_item_id_has_vtable(&self, id: TypeId) -> bool { + pub fn lookup_has_vtable(&self, id: TypeId) -> bool { assert!( self.in_codegen_phase(), "We only compute vtables when we enter codegen" @@ -1272,7 +1272,7 @@ impl BindgenContext { } /// Look up whether the item with `id` has a destructor. - pub fn lookup_item_id_has_destructor(&self, id: TypeId) -> bool { + pub fn lookup_has_destructor(&self, id: TypeId) -> bool { assert!( self.in_codegen_phase(), "We only compute destructors when we enter codegen" @@ -2289,7 +2289,7 @@ impl BindgenContext { /// Look up whether the item with `id` can /// derive debug or not. - pub fn lookup_item_id_can_derive_debug>(&self, id: Id) -> bool { + pub fn lookup_can_derive_debug>(&self, id: Id) -> bool { let id = id.into(); assert!( self.in_codegen_phase(), @@ -2313,7 +2313,7 @@ impl BindgenContext { /// Look up whether the item with `id` can /// derive default or not. - pub fn lookup_item_id_can_derive_default>(&self, id: Id) -> bool { + pub fn lookup_can_derive_default>(&self, id: Id) -> bool { let id = id.into(); assert!( self.in_codegen_phase(), @@ -2343,7 +2343,7 @@ impl BindgenContext { /// Look up whether the item with `id` can /// derive hash or not. - pub fn lookup_item_id_can_derive_hash>(&self, id: Id) -> bool { + pub fn lookup_can_derive_hash>(&self, id: Id) -> bool { let id = id.into(); assert!( self.in_codegen_phase(), @@ -2365,7 +2365,7 @@ impl BindgenContext { } /// Look up whether the item with `id` can derive `Partial{Eq,Ord}`. - pub fn lookup_item_id_can_derive_partialeq_or_partialord>(&self, id: Id) -> bool { + pub fn lookup_can_derive_partialeq_or_partialord>(&self, id: Id) -> bool { let id = id.into(); assert!( self.in_codegen_phase(), @@ -2378,7 +2378,7 @@ impl BindgenContext { } /// Look up whether the item with `id` can derive `Copy` or not. - pub fn lookup_item_id_can_derive_copy>(&self, id: Id) -> bool { + pub fn lookup_can_derive_copy>(&self, id: Id) -> bool { assert!( self.in_codegen_phase(), "We only compute can_derive_debug when we enter codegen" @@ -2387,7 +2387,7 @@ impl BindgenContext { // Look up the computed value for whether the item with `id` can // derive `Copy` or not. let id = id.into(); - !self.lookup_item_id_has_type_param_in_array(id) && + !self.lookup_has_type_param_in_array(id) && !self.cannot_derive_copy.as_ref().unwrap().contains(&id) } @@ -2400,7 +2400,7 @@ impl BindgenContext { } /// Look up whether the item with `id` has type parameter in array or not. - pub fn lookup_item_id_has_type_param_in_array>(&self, id: Id) -> bool { + pub fn lookup_has_type_param_in_array>(&self, id: Id) -> bool { assert!( self.in_codegen_phase(), "We only compute has array when we enter codegen" @@ -2421,7 +2421,7 @@ impl BindgenContext { } /// Look up whether the item with `id` has array or not. - pub fn lookup_item_id_has_float>(&self, id: Id) -> bool { + pub fn lookup_has_float>(&self, id: Id) -> bool { assert!(self.in_codegen_phase(), "We only compute has float when we enter codegen"); diff --git a/src/ir/item.rs b/src/ir/item.rs index 31d420806b..010528b6d0 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -320,57 +320,57 @@ impl Trace for Item { impl CanDeriveDebug for Item { fn can_derive_debug(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_debug && - ctx.lookup_item_id_can_derive_debug(self.id()) + ctx.lookup_can_derive_debug(self.id()) } } impl CanDeriveDefault for Item { fn can_derive_default(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_default && - ctx.lookup_item_id_can_derive_default(self.id()) + ctx.lookup_can_derive_default(self.id()) } } impl<'a> CanDeriveCopy<'a> for Item { fn can_derive_copy(&self, ctx: &BindgenContext) -> bool { - ctx.lookup_item_id_can_derive_copy(self.id()) + ctx.lookup_can_derive_copy(self.id()) } } impl CanDeriveHash for Item { fn can_derive_hash(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_hash && - ctx.lookup_item_id_can_derive_hash(self.id()) + ctx.lookup_can_derive_hash(self.id()) } } impl CanDerivePartialOrd for Item { fn can_derive_partialord(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_partialord && - ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) + ctx.lookup_can_derive_partialeq_or_partialord(self.id()) } } impl CanDerivePartialEq for Item { fn can_derive_partialeq(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_partialeq && - ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) + ctx.lookup_can_derive_partialeq_or_partialord(self.id()) } } impl CanDeriveEq for Item { fn can_derive_eq(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_eq && - ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) && - !ctx.lookup_item_id_has_float(self.id()) + ctx.lookup_can_derive_partialeq_or_partialord(self.id()) && + !ctx.lookup_has_float(self.id()) } } impl CanDeriveOrd for Item { fn can_derive_ord(&self, ctx: &BindgenContext) -> bool { ctx.options().derive_ord && - ctx.lookup_item_id_can_derive_partialeq_or_partialord(self.id()) && - !ctx.lookup_item_id_has_float(self.id()) + ctx.lookup_can_derive_partialeq_or_partialord(self.id()) && + !ctx.lookup_has_float(self.id()) } } @@ -1001,7 +1001,7 @@ where fn has_vtable(&self, ctx: &BindgenContext) -> bool { let id: ItemId = (*self).into(); id.as_type_id(ctx) - .map_or(false, |id| ctx.lookup_item_id_has_vtable(id)) + .map_or(false, |id| ctx.lookup_has_vtable(id)) } } @@ -1009,7 +1009,7 @@ impl HasVtable for Item { fn has_vtable(&self, ctx: &BindgenContext) -> bool { self.id() .as_type_id(ctx) - .map_or(false, |id| ctx.lookup_item_id_has_vtable(id)) + .map_or(false, |id| ctx.lookup_has_vtable(id)) } } @@ -1022,7 +1022,7 @@ where ctx.in_codegen_phase(), "You're not supposed to call this yet" ); - ctx.lookup_item_id_has_type_param_in_array(*self) + ctx.lookup_has_type_param_in_array(*self) } } @@ -1032,7 +1032,7 @@ impl HasTypeParamInArray for Item { ctx.in_codegen_phase(), "You're not supposed to call this yet" ); - ctx.lookup_item_id_has_type_param_in_array(self.id()) + ctx.lookup_has_type_param_in_array(self.id()) } } @@ -1043,7 +1043,7 @@ where fn has_float(&self, ctx: &BindgenContext) -> bool { debug_assert!(ctx.in_codegen_phase(), "You're not supposed to call this yet"); - ctx.lookup_item_id_has_float(*self) + ctx.lookup_has_float(*self) } } @@ -1051,7 +1051,7 @@ impl HasFloat for Item { fn has_float(&self, ctx: &BindgenContext) -> bool { debug_assert!(ctx.in_codegen_phase(), "You're not supposed to call this yet"); - ctx.lookup_item_id_has_float(self.id()) + ctx.lookup_has_float(self.id()) } }