diff options
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r-- | src/codegen/mod.rs | 759 |
1 files changed, 410 insertions, 349 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 8e1eded2..c7f1b2bd 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1,7 +1,7 @@ -mod impl_debug; -mod impl_partialeq; mod error; mod helpers; +mod impl_debug; +mod impl_partialeq; pub mod struct_layout; #[cfg(test)] @@ -18,12 +18,15 @@ use super::BindgenOptions; use ir::analysis::{HasVtable, Sizedness}; use ir::annotations::FieldAccessorKind; use ir::comment; -use ir::comp::{Base, Bitfield, BitfieldUnit, CompInfo, CompKind, Field, - FieldData, FieldMethods, Method, MethodKind}; +use ir::comp::{ + Base, Bitfield, BitfieldUnit, CompInfo, CompKind, Field, FieldData, + FieldMethods, Method, MethodKind, +}; use ir::context::{BindgenContext, ItemId}; -use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, - CanDeriveHash, CanDerivePartialOrd, CanDeriveOrd, - CanDerivePartialEq, CanDeriveEq, CanDerive}; +use ir::derive::{ + CanDerive, CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveEq, + CanDeriveHash, CanDeriveOrd, CanDerivePartialEq, CanDerivePartialOrd, +}; use ir::dot; use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue}; use ir::function::{Abi, Function, FunctionKind, FunctionSig, Linkage}; @@ -33,12 +36,14 @@ use ir::item_kind::ItemKind; use ir::layout::Layout; use ir::module::Module; use ir::objc::{ObjCInterface, ObjCMethod}; -use ir::template::{AsTemplateParam, TemplateInstantiation, TemplateParameters}; +use ir::template::{ + AsTemplateParam, TemplateInstantiation, TemplateParameters, +}; use ir::ty::{Type, TypeKind}; use ir::var::Var; -use quote::TokenStreamExt; use proc_macro2::{self, Ident, Span}; +use quote::TokenStreamExt; use std; use std::borrow::Cow; @@ -48,12 +53,15 @@ use std::fmt::Write; use std::iter; use std::ops; use std::str::FromStr; -use {HashMap, HashSet, Entry}; +use {Entry, HashMap, HashSet}; // Name of type defined in constified enum module pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &'static str = "Type"; -fn top_level_path(ctx: &BindgenContext, item: &Item) -> Vec<proc_macro2::TokenStream> { +fn top_level_path( + ctx: &BindgenContext, + item: &Item, +) -> Vec<proc_macro2::TokenStream> { let mut path = vec![quote! { self }]; if ctx.options().enable_cxx_namespaces { @@ -65,7 +73,10 @@ fn top_level_path(ctx: &BindgenContext, item: &Item) -> Vec<proc_macro2::TokenSt path } -fn root_import(ctx: &BindgenContext, module: &Item) -> proc_macro2::TokenStream { +fn root_import( + ctx: &BindgenContext, + module: &Item, +) -> proc_macro2::TokenStream { assert!(ctx.options().enable_cxx_namespaces, "Somebody messed it up"); assert!(module.is_module()); @@ -75,7 +86,6 @@ fn root_import(ctx: &BindgenContext, module: &Item) -> proc_macro2::TokenStream let root_ident = ctx.rust_ident(&root); path.push(quote! { #root_ident }); - let mut tokens = quote! {}; tokens.append_separated(path, quote!(::)); @@ -268,10 +278,7 @@ impl AppendImplicitTemplateParams for proc_macro2::TokenStream { ctx: &BindgenContext, item: &Item, ) { - let item = item.id() - .into_resolver() - .through_type_refs() - .resolve(ctx); + let item = item.id().into_resolver().through_type_refs().resolve(ctx); match *item.expect_type().kind() { TypeKind::UnresolvedTypeRef(..) => { @@ -297,13 +304,17 @@ impl AppendImplicitTemplateParams for proc_macro2::TokenStream { TypeKind::ObjCId | TypeKind::ObjCSel | TypeKind::TemplateInstantiation(..) => return, - _ => {}, + _ => {} } - let params: Vec<_> = item.used_template_params(ctx).iter().map(|p| { - p.try_to_rust_ty(ctx, &()) - .expect("template params cannot fail to be a rust type") - }).collect(); + let params: Vec<_> = item + .used_template_params(ctx) + .iter() + .map(|p| { + p.try_to_rust_ty(ctx, &()) + .expect("template params cannot fail to be a rust type") + }) + .collect(); if !params.is_empty() { self.append_all(quote! { < #( #params ),* > @@ -431,7 +442,9 @@ impl CodeGenerator for Module { if let Some(raw_lines) = ctx.options().module_lines.get(&path) { for raw_line in raw_lines { found_any = true; - result.push(proc_macro2::TokenStream::from_str(raw_line).unwrap()); + result.push( + proc_macro2::TokenStream::from_str(raw_line).unwrap(), + ); } } @@ -500,7 +513,8 @@ impl CodeGenerator for Var { }); } VarType::Int(val) => { - let int_kind = self.ty() + let int_kind = self + .ty() .into_resolver() .through_type_aliases() .through_type_refs() @@ -570,7 +584,7 @@ impl CodeGenerator for Var { } let maybe_mut = if self.is_const() { - quote! { } + quote! {} } else { quote! { mut } }; @@ -627,13 +641,14 @@ impl CodeGenerator for Type { return; } - let inner_item = inner.into_resolver() - .through_type_refs() - .resolve(ctx); + let inner_item = + inner.into_resolver().through_type_refs().resolve(ctx); let name = item.canonical_name(ctx); let inner_rust_type = { - if let TypeKind::Function(fnsig) = inner_item.kind().expect_type().kind() { + if let TypeKind::Function(fnsig) = + inner_item.kind().expect_type().kind() + { utils::fnsig_block(ctx, fnsig) } else { panic!("invalid block typedef: {:?}", inner_item) @@ -656,16 +671,15 @@ impl CodeGenerator for Type { result.saw_block(); } TypeKind::Comp(ref ci) => ci.codegen(ctx, result, item), - TypeKind::TemplateAlias(inner, _) | - TypeKind::Alias(inner) => { - let inner_item = inner.into_resolver() - .through_type_refs() - .resolve(ctx); + TypeKind::TemplateAlias(inner, _) | TypeKind::Alias(inner) => { + let inner_item = + inner.into_resolver().through_type_refs().resolve(ctx); let name = item.canonical_name(ctx); let path = item.canonical_path(ctx); { - let through_type_aliases = inner.into_resolver() + let through_type_aliases = inner + .into_resolver() .through_type_refs() .through_type_aliases() .resolve(ctx); @@ -720,8 +734,7 @@ impl CodeGenerator for Type { warn!( "Item contained invalid named type, skipping: \ {:?}, {:?}", - item, - inner_item + item, inner_item ); return; } @@ -737,15 +750,12 @@ impl CodeGenerator for Type { // We prefer using `pub use` over `pub type` because of: // https://github.com/rust-lang/rust/issues/26264 - if inner_rust_type.to_string() - .chars() - .all(|c| match c { - // These are the only characters allowed in simple - // paths, eg `good::dogs::Bront`. - 'A'..='Z' | 'a'..='z' | '0'..='9' | ':' | '_' | ' ' => true, - _ => false, - }) && - outer_params.is_empty() && + if inner_rust_type.to_string().chars().all(|c| match c { + // These are the only characters allowed in simple + // paths, eg `good::dogs::Bront`. + 'A'..='Z' | 'a'..='z' | '0'..='9' | ':' | '_' | ' ' => true, + _ => false, + }) && outer_params.is_empty() && inner_item.expect_type().canonical_type(ctx).is_enum() { tokens.append_all(quote! { @@ -764,10 +774,14 @@ impl CodeGenerator for Type { pub type #rust_name }); - let params: Vec<_> = outer_params.into_iter() + let params: Vec<_> = outer_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).is_invalid_type_param()) + { warn!( "Item contained invalid template \ parameter: {:?}", @@ -775,10 +789,14 @@ impl CodeGenerator for Type { ); return; } - let params: Vec<_> = params.iter().map(|p| { - p.try_to_rust_ty(ctx, &()) - .expect("type parameters can always convert to rust ty OK") - }).collect(); + let params: Vec<_> = params + .iter() + .map(|p| { + p.try_to_rust_ty(ctx, &()).expect( + "type parameters can always convert to rust ty OK", + ) + }) + .collect(); if !params.is_empty() { tokens.append_all(quote! { @@ -1038,7 +1056,8 @@ impl<'a> FieldCodegen<'a> for FieldData { // `BitfieldUnit` and `Bitfield`. assert!(self.bitfield_width().is_none()); - let field_item = self.ty().into_resolver().through_type_refs().resolve(ctx); + let field_item = + self.ty().into_resolver().through_type_refs().resolve(ctx); let field_ty = field_item.expect_type(); let mut ty = self.ty().to_rust_ty_or_opaque(ctx, &()); ty.append_implicit_template_params(ctx, field_item); @@ -1082,10 +1101,10 @@ impl<'a> FieldCodegen<'a> for FieldData { } } - let field_name = - self.name() - .map(|name| ctx.rust_mangle(name).into_owned()) - .expect("Each field should have a name in codegen!"); + let field_name = self + .name() + .map(|name| ctx.rust_mangle(name).into_owned()) + .expect("Each field should have a name in codegen!"); let field_ident = ctx.rust_ident_raw(field_name.as_str()); if !parent.is_union() { @@ -1096,9 +1115,10 @@ impl<'a> FieldCodegen<'a> for FieldData { } } - let is_private = self.annotations().private_fields().unwrap_or( - fields_should_be_private, - ); + let is_private = self + .annotations() + .private_fields() + .unwrap_or(fields_should_be_private); let accessor_kind = self.annotations().accessor_kind().unwrap_or(accessor_kind); @@ -1168,7 +1188,10 @@ impl<'a> FieldCodegen<'a> for FieldData { impl BitfieldUnit { /// Get the constructor name for this bitfield unit. fn ctor_name(&self) -> proc_macro2::TokenStream { - let ctor_name = Ident::new(&format!("new_bitfield_{}", self.nth()), Span::call_site()); + let ctor_name = Ident::new( + &format!("new_bitfield_{}", self.nth()), + Span::call_site(), + ); quote! { #ctor_name } @@ -1190,9 +1213,9 @@ impl Bitfield { mut ctor_impl: proc_macro2::TokenStream, ) -> proc_macro2::TokenStream { let bitfield_ty = ctx.resolve_type(self.ty()); - let bitfield_ty_layout = bitfield_ty.layout(ctx).expect( - "Bitfield without layout? Gah!", - ); + let bitfield_ty_layout = bitfield_ty + .layout(ctx) + .expect("Bitfield without layout? Gah!"); let bitfield_int_ty = helpers::blob(ctx, bitfield_ty_layout); let offset = self.offset_into_unit(); @@ -1306,11 +1329,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { ctor_params.push(quote! { #param_name : #bitfield_ty }); - ctor_impl = bf.extend_ctor_impl( - ctx, - param_name, - ctor_impl, - ); + ctor_impl = bf.extend_ctor_impl(ctx, param_name, ctor_impl); } if generate_ctor { @@ -1373,19 +1392,20 @@ impl<'a> FieldCodegen<'a> for Bitfield { let bitfield_ty_item = ctx.resolve_item(self.ty()); let bitfield_ty = bitfield_ty_item.expect_type(); - let bitfield_ty_layout = bitfield_ty.layout(ctx).expect( - "Bitfield without layout? Gah!", - ); - let bitfield_int_ty = match helpers::integer_type(ctx, bitfield_ty_layout) { - Some(int_ty) => { - *bitfield_representable_as_int = true; - int_ty - } - None => { - *bitfield_representable_as_int = false; - return; - } - }; + let bitfield_ty_layout = bitfield_ty + .layout(ctx) + .expect("Bitfield without layout? Gah!"); + let bitfield_int_ty = + match helpers::integer_type(ctx, bitfield_ty_layout) { + Some(int_ty) => { + *bitfield_representable_as_int = true; + int_ty + } + None => { + *bitfield_representable_as_int = false; + return; + } + }; let bitfield_ty = bitfield_ty.to_rust_ty_or_opaque(ctx, bitfield_ty_item); @@ -1529,7 +1549,8 @@ impl CodeGenerator for CompInfo { let codegen_depth = item.codegen_depth(ctx); let fields_should_be_private = item.annotations().private_fields().unwrap_or(false); - let struct_accessor_kind = item.annotations() + let struct_accessor_kind = item + .annotations() .accessor_kind() .unwrap_or(FieldAccessorKind::None); for field in self.fields() { @@ -1584,7 +1605,10 @@ impl CodeGenerator for CompInfo { } else { explicit_align = Some(layout.align); if !ctx.options().rust_features.repr_align { - let ty = helpers::blob(ctx, Layout::new(0, layout.align)); + let ty = helpers::blob( + ctx, + Layout::new(0, layout.align), + ); fields.push(quote! { pub __bindgen_align: #ty , }); @@ -1668,7 +1692,7 @@ impl CodeGenerator for CompInfo { < #( #generic_param_names ),* > } } else { - quote! { } + quote! {} }; let mut attributes = vec![]; @@ -1682,7 +1706,11 @@ impl CodeGenerator for CompInfo { if packed && !is_opaque { let n = layout.map_or(1, |l| l.align); assert!(ctx.options().rust_features().repr_packed_n || n == 1); - let packed_repr = if n == 1 { "packed".to_string() } else { format!("packed({})", n) }; + let packed_repr = if n == 1 { + "packed".to_string() + } else { + format!("packed({})", n) + }; attributes.push(attributes::repr_list(&["C", &packed_repr])); } else { attributes.push(attributes::repr("C")); @@ -1699,13 +1727,12 @@ impl CodeGenerator for CompInfo { } } - let mut derives = vec![]; if item.can_derive_debug(ctx) { derives.push("Debug"); } else { - needs_debug_impl = ctx.options().derive_debug && - ctx.options().impl_debug + needs_debug_impl = + ctx.options().derive_debug && ctx.options().impl_debug } if item.can_derive_default(ctx) { @@ -1750,10 +1777,10 @@ impl CodeGenerator for CompInfo { if item.can_derive_partialeq(ctx) { derives.push("PartialEq"); } else { - needs_partialeq_impl = - ctx.options().derive_partialeq && + needs_partialeq_impl = ctx.options().derive_partialeq && ctx.options().impl_partialeq && - ctx.lookup_can_derive_partialeq_or_partialord(item.id()) == CanDerive::Manually; + ctx.lookup_can_derive_partialeq_or_partialord(item.id()) == + CanDerive::Manually; } if item.can_derive_eq(ctx) { @@ -1827,34 +1854,36 @@ impl CodeGenerator for CompInfo { let size = layout.size; let align = layout.align; - let check_struct_align = - if align > ctx.target_pointer_size() && - !ctx.options().rust_features().repr_align - { - None - } else { - Some(quote! { - assert_eq!(#align_of_expr, - #align, - concat!("Alignment of ", stringify!(#canonical_ident))); + let check_struct_align = if align > + ctx.target_pointer_size() && + !ctx.options().rust_features().repr_align + { + None + } else { + Some(quote! { + assert_eq!(#align_of_expr, + #align, + concat!("Alignment of ", stringify!(#canonical_ident))); - }) - }; + }) + }; // FIXME when [issue #465](https://github.com/rust-lang/rust-bindgen/issues/465) ready - let too_many_base_vtables = self.base_members() + let too_many_base_vtables = self + .base_members() .iter() .filter(|base| base.ty.has_vtable(ctx)) - .count() > 1; + .count() > + 1; - let should_skip_field_offset_checks = is_opaque || - too_many_base_vtables; + let should_skip_field_offset_checks = + is_opaque || too_many_base_vtables; - let check_field_offset = - if should_skip_field_offset_checks { - vec![] - } else { - let asserts = self.fields() + let check_field_offset = if should_skip_field_offset_checks + { + vec![] + } else { + let asserts = self.fields() .iter() .filter_map(|field| match *field { Field::DataMember(ref f) if f.name().is_some() => Some(f), @@ -1879,8 +1908,8 @@ impl CodeGenerator for CompInfo { }) .collect::<Vec<proc_macro2::TokenStream>>(); - asserts - }; + asserts + }; let item = quote! { #[test] @@ -1918,7 +1947,8 @@ impl CodeGenerator for CompInfo { *sig, /* const */ false, - ).codegen_method( + ) + .codegen_method( ctx, &mut methods, &mut method_names, @@ -1983,15 +2013,19 @@ impl CodeGenerator for CompInfo { } if needs_partialeq_impl { - if let Some(impl_) = impl_partialeq::gen_partialeq_impl(ctx, self, item, &ty_for_impl) { - + if let Some(impl_) = impl_partialeq::gen_partialeq_impl( + ctx, + self, + item, + &ty_for_impl, + ) { let partialeq_bounds = if !generic_param_names.is_empty() { let bounds = generic_param_names.iter().map(|t| { quote! { #t: PartialEq } }); quote! { where #( #bounds ),* } } else { - quote! { } + quote! {} }; let prefix = ctx.trait_prefix(); @@ -2067,7 +2101,9 @@ impl MethodCodegen for Method { _ => panic!("How in the world?"), }; - if let (Abi::ThisCall, false) = (signature.abi(), ctx.options().rust_features().thiscall_abi) { + if let (Abi::ThisCall, false) = + (signature.abi(), ctx.options().rust_features().thiscall_abi) + { return; } @@ -2118,10 +2154,9 @@ impl MethodCodegen for Method { // variable called `__bindgen_tmp` we're going to create. if self.is_constructor() { let prefix = ctx.trait_prefix(); - let tmp_variable_decl = - quote! { - let mut __bindgen_tmp = ::#prefix::mem::uninitialized() - }; + let tmp_variable_decl = quote! { + let mut __bindgen_tmp = ::#prefix::mem::uninitialized() + }; stmts.push(tmp_variable_decl); exprs[0] = quote! { &mut __bindgen_tmp @@ -2152,7 +2187,9 @@ impl MethodCodegen for Method { let mut attrs = vec![]; attrs.push(attributes::inline()); - if signature.must_use() && ctx.options().rust_features().must_use_function { + if signature.must_use() && + ctx.options().rust_features().must_use_function + { attrs.push(attributes::must_use()); } @@ -2172,21 +2209,21 @@ pub enum EnumVariation { /// The code for this enum will use a Rust enum Rust { /// Indicates whether the generated struct should be #[non_exhaustive] - non_exhaustive: bool + non_exhaustive: bool, }, /// The code for this enum will use a bitfield Bitfield, /// The code for this enum will use consts Consts, /// The code for this enum will use a module containing consts - ModuleConsts + ModuleConsts, } impl EnumVariation { fn is_rust(&self) -> bool { match *self { - EnumVariation::Rust{ .. } => true, - _ => false + EnumVariation::Rust { .. } => true, + _ => false, } } @@ -2195,7 +2232,7 @@ impl EnumVariation { fn is_const(&self) -> bool { match *self { EnumVariation::Consts | EnumVariation::ModuleConsts => true, - _ => false + _ => false, } } } @@ -2225,7 +2262,6 @@ impl std::str::FromStr for EnumVariation { } } - /// A helper type to construct different enum variations. enum EnumBuilder<'a> { Rust { @@ -2274,16 +2310,14 @@ impl<'a> EnumBuilder<'a> { let ident = Ident::new(name, Span::call_site()); match enum_variation { - EnumVariation::Bitfield => { - EnumBuilder::Bitfield { - codegen_depth: enum_codegen_depth, - canonical_name: name, - tokens: quote! { - #( #attrs )* - pub struct #ident (pub #repr); - }, - } - } + EnumVariation::Bitfield => EnumBuilder::Bitfield { + codegen_depth: enum_codegen_depth, + canonical_name: name, + tokens: quote! { + #( #attrs )* + pub struct #ident (pub #repr); + }, + }, EnumVariation::Rust { .. } => { let tokens = quote!(); @@ -2296,20 +2330,19 @@ impl<'a> EnumBuilder<'a> { } } - EnumVariation::Consts => { - EnumBuilder::Consts { - variants: vec![ - quote! { - #( #attrs )* - pub type #ident = #repr; - } - ], - codegen_depth: enum_codegen_depth, - } - } + EnumVariation::Consts => EnumBuilder::Consts { + variants: vec![quote! { + #( #attrs )* + pub type #ident = #repr; + }], + codegen_depth: enum_codegen_depth, + }, EnumVariation::ModuleConsts => { - let ident = Ident::new(CONSTIFIED_ENUM_MODULE_REPR_NAME, Span::call_site()); + let ident = Ident::new( + CONSTIFIED_ENUM_MODULE_REPR_NAME, + Span::call_site(), + ); let type_definition = quote! { #( #attrs )* pub type #ident = #repr; @@ -2343,13 +2376,20 @@ impl<'a> EnumBuilder<'a> { let mut doc = quote! {}; if ctx.options().generate_comments { if let Some(raw_comment) = variant.comment() { - let comment = comment::preprocess(raw_comment, self.codegen_depth()); + let comment = + comment::preprocess(raw_comment, self.codegen_depth()); doc = attributes::doc(comment); } } match self { - EnumBuilder::Rust { attrs, ident, tokens, emitted_any_variants: _, codegen_depth } => { + EnumBuilder::Rust { + attrs, + ident, + tokens, + emitted_any_variants: _, + codegen_depth, + } => { let name = ctx.rust_ident(variant_name); EnumBuilder::Rust { attrs, @@ -2365,7 +2405,8 @@ impl<'a> EnumBuilder<'a> { } EnumBuilder::Bitfield { canonical_name, .. } => { - if ctx.options().rust_features().associated_const && is_ty_named { + if ctx.options().rust_features().associated_const && is_ty_named + { let enum_ident = ctx.rust_ident(canonical_name); let variant_ident = ctx.rust_ident(variant_name); result.push(quote! { @@ -2390,9 +2431,7 @@ impl<'a> EnumBuilder<'a> { self } - EnumBuilder::Consts { - .. - } => { + EnumBuilder::Consts { .. } => { let constant_name = match mangling_prefix { Some(prefix) => { Cow::Owned(format!("{}_{}", prefix, variant_name)) @@ -2436,7 +2475,13 @@ impl<'a> EnumBuilder<'a> { result: &mut CodegenResult<'b>, ) -> proc_macro2::TokenStream { match self { - EnumBuilder::Rust { attrs, ident, tokens, emitted_any_variants, .. } => { + EnumBuilder::Rust { + attrs, + ident, + tokens, + emitted_any_variants, + .. + } => { let variants = if !emitted_any_variants { quote!(__bindgen_cannot_repr_c_on_empty_enum = 0) } else { @@ -2536,12 +2581,10 @@ impl CodeGenerator for Enum { let repr = self.repr().map(|repr| ctx.resolve_type(repr)); let repr = match repr { - Some(repr) => { - match *repr.canonical_type(ctx).kind() { - TypeKind::Int(int_kind) => int_kind, - _ => panic!("Unexpected type as enum repr"), - } - } + Some(repr) => match *repr.canonical_type(ctx).kind() { + TypeKind::Int(int_kind) => int_kind, + _ => panic!("Unexpected type as enum repr"), + }, None => { warn!( "Guessing type of enum! Forward declarations of enums \ @@ -2580,20 +2623,24 @@ impl CodeGenerator for Enum { match variation { EnumVariation::Rust { non_exhaustive } => { attrs.push(attributes::repr(repr_name)); - if non_exhaustive && ctx.options().rust_features().non_exhaustive { + if non_exhaustive && + ctx.options().rust_features().non_exhaustive + { attrs.push(attributes::non_exhaustive()); - } else if non_exhaustive && !ctx.options().rust_features().non_exhaustive { + } else if non_exhaustive && + !ctx.options().rust_features().non_exhaustive + { panic!("The rust target you're using doesn't seem to support non_exhaustive enums"); } - }, + } EnumVariation::Bitfield => { if ctx.options().rust_features.repr_transparent { attrs.push(attributes::repr("transparent")); } else { attrs.push(attributes::repr("C")); } - }, - _ => {}, + } + _ => {} }; if let Some(comment) = item.comment(ctx) { @@ -2601,7 +2648,8 @@ impl CodeGenerator for Enum { } if !variation.is_const() { - let mut derives = vec!["Debug", "Copy", "Clone", "PartialEq", "Eq", "Hash"]; + let mut derives = + vec!["Debug", "Copy", "Clone", "PartialEq", "Eq", "Hash"]; if item.can_derive_partialord(ctx) { derives.push("PartialOrd"); @@ -2685,9 +2733,9 @@ impl CodeGenerator for Enum { let mut constified_variants = VecDeque::new(); let mut iter = self.variants().iter().peekable(); - while let Some(variant) = iter.next().or_else(|| { - constified_variants.pop_front() - }) { + while let Some(variant) = + iter.next().or_else(|| constified_variants.pop_front()) + { if variant.hidden() { continue; } @@ -2708,17 +2756,20 @@ impl CodeGenerator for Enum { let parent_name = parent_canonical_name.as_ref().unwrap(); - Cow::Owned( - format!("{}_{}", parent_name, variant_name), - ) + Cow::Owned(format!( + "{}_{}", + parent_name, variant_name + )) }; let existing_variant_name = entry.get(); // Use associated constants for named enums. if enum_ty.name().is_some() && - ctx.options().rust_features().associated_const { + ctx.options().rust_features().associated_const + { let enum_canonical_name = &ident; - let variant_name = ctx.rust_ident_raw(&*mangled_name); + let variant_name = + ctx.rust_ident_raw(&*mangled_name); result.push(quote! { impl #enum_rust_ty { pub const #variant_name : #enum_rust_ty = @@ -2772,12 +2823,8 @@ impl CodeGenerator for Enum { parent_canonical_name.as_ref().unwrap(); Ident::new( - &format!( - "{}_{}", - parent_name, - variant_name - ), - Span::call_site() + &format!("{}_{}", parent_name, variant_name), + Span::call_site(), ) }; @@ -2823,9 +2870,8 @@ trait TryToOpaque { ctx: &BindgenContext, extra: &Self::Extra, ) -> error::Result<proc_macro2::TokenStream> { - self.try_get_layout(ctx, extra).map(|layout| { - helpers::blob(ctx, layout) - }) + self.try_get_layout(ctx, extra) + .map(|layout| helpers::blob(ctx, layout)) } } @@ -2855,11 +2901,7 @@ trait ToOpaque: TryToOpaque { } } -impl<T> ToOpaque for T -where - T: TryToOpaque, -{ -} +impl<T> ToOpaque for T where T: TryToOpaque {} /// Fallible conversion from an IR thing to an *equivalent* Rust type. /// @@ -2895,8 +2937,7 @@ trait TryToRustTyOrOpaque: TryToRustTy + TryToOpaque { impl<E, T> TryToRustTyOrOpaque for T where - T: TryToRustTy<Extra = E> - + TryToOpaque<Extra = E>, + T: TryToRustTy<Extra = E> + TryToOpaque<Extra = E>, { type Extra = E; @@ -2905,15 +2946,13 @@ where ctx: &BindgenContext, extra: &E, ) -> error::Result<proc_macro2::TokenStream> { - self.try_to_rust_ty(ctx, extra).or_else( - |_| if let Ok(layout) = - self.try_get_layout(ctx, extra) - { + self.try_to_rust_ty(ctx, extra).or_else(|_| { + if let Ok(layout) = self.try_get_layout(ctx, extra) { Ok(helpers::blob(ctx, layout)) } else { Err(error::Error::NoLayoutForOpaqueBlob) - }, - ) + } + }) } } @@ -2955,15 +2994,14 @@ where ctx: &BindgenContext, extra: &E, ) -> proc_macro2::TokenStream { - self.try_to_rust_ty(ctx, extra).unwrap_or_else(|_| { - self.to_opaque(ctx, extra) - }) + self.try_to_rust_ty(ctx, extra) + .unwrap_or_else(|_| self.to_opaque(ctx, extra)) } } impl<T> TryToOpaque for T where - T: Copy + Into<ItemId> + T: Copy + Into<ItemId>, { type Extra = (); @@ -2978,7 +3016,7 @@ where impl<T> TryToRustTy for T where - T: Copy + Into<ItemId> + T: Copy + Into<ItemId>, { type Extra = (); @@ -3041,15 +3079,11 @@ impl TryToRustTy for Type { TypeKind::Void => Ok(raw_type(ctx, "c_void")), // TODO: we should do something smart with nullptr, or maybe *const // c_void is enough? - TypeKind::NullPtr => { - Ok(raw_type(ctx, "c_void").to_ptr(true)) - } + TypeKind::NullPtr => Ok(raw_type(ctx, "c_void").to_ptr(true)), TypeKind::Int(ik) => { match ik { IntKind::Bool => Ok(quote! { bool }), - IntKind::Char { - .. - } => Ok(raw_type(ctx, "c_char")), + IntKind::Char { .. } => Ok(raw_type(ctx, "c_char")), IntKind::SChar => Ok(raw_type(ctx, "c_schar")), IntKind::UChar => Ok(raw_type(ctx, "c_uchar")), IntKind::Short => Ok(raw_type(ctx, "c_short")), @@ -3061,12 +3095,14 @@ impl TryToRustTy for Type { IntKind::LongLong => Ok(raw_type(ctx, "c_longlong")), IntKind::ULongLong => Ok(raw_type(ctx, "c_ulonglong")), IntKind::WChar => { - let layout = self.layout(ctx).expect("Couldn't compute wchar_t's layout?"); + let layout = self + .layout(ctx) + .expect("Couldn't compute wchar_t's layout?"); let ty = Layout::known_type_for_size(ctx, layout.size) .expect("Non-representable wchar_t?"); let ident = ctx.rust_ident_raw(ty); Ok(quote! { #ident }) - }, + } IntKind::I8 => Ok(quote! { i8 }), IntKind::U8 => Ok(quote! { u8 }), @@ -3076,9 +3112,7 @@ impl TryToRustTy for Type { IntKind::U32 => Ok(quote! { u32 }), IntKind::I64 => Ok(quote! { i64 }), IntKind::U64 => Ok(quote! { u64 }), - IntKind::Custom { - name, .. - } => { + IntKind::Custom { name, .. } => { let ident = ctx.rust_ident_raw(name); Ok(quote! { #ident @@ -3102,9 +3136,12 @@ impl TryToRustTy for Type { } } } - TypeKind::Float(fk) => Ok(float_kind_rust_type(ctx, fk, self.layout(ctx))), + TypeKind::Float(fk) => { + Ok(float_kind_rust_type(ctx, fk, self.layout(ctx))) + } TypeKind::Complex(fk) => { - let float_path = float_kind_rust_type(ctx, fk, self.layout(ctx)); + let float_path = + float_kind_rust_type(ctx, fk, self.layout(ctx)); ctx.generated_bindgen_complex(); Ok(if ctx.options().enable_cxx_namespaces { @@ -3137,7 +3174,8 @@ impl TryToRustTy for Type { } TypeKind::Enum(..) => { let path = item.namespace_aware_canonical_path(ctx); - let path = proc_macro2::TokenStream::from_str(&path.join("::")).unwrap(); + let path = proc_macro2::TokenStream::from_str(&path.join("::")) + .unwrap(); Ok(quote!(#path)) } TypeKind::TemplateInstantiation(ref inst) => { @@ -3151,14 +3189,18 @@ impl TryToRustTy for Type { let void = raw_type(ctx, "c_void"); return Ok(void.to_ptr(/* is_const = */ false)); } - let template_params = item.used_template_params(ctx) + let template_params = item + .used_template_params(ctx) .into_iter() .filter(|param| param.is_template_param(ctx, &())) .collect::<Vec<_>>(); if item.is_opaque(ctx, &()) && !template_params.is_empty() { self.try_to_opaque(ctx, item) - } else if let Some(ty) = self.name().and_then(|name| utils::type_from_named(ctx, name)) { + } else if let Some(ty) = self + .name() + .and_then(|name| utils::type_from_named(ctx, name)) + { Ok(ty) } else { utils::build_path(item, ctx) @@ -3175,11 +3217,11 @@ impl TryToRustTy for Type { utils::build_path(item, ctx) } TypeKind::Opaque => self.try_to_opaque(ctx, item), - TypeKind::Pointer(inner) | - TypeKind::Reference(inner) => { + TypeKind::Pointer(inner) | TypeKind::Reference(inner) => { let is_const = ctx.resolve_type(inner).is_const(); - let inner = inner.into_resolver().through_type_refs().resolve(ctx); + let inner = + inner.into_resolver().through_type_refs().resolve(ctx); let inner_ty = inner.expect_type(); // Regardless if we can properly represent the inner type, we @@ -3203,13 +3245,10 @@ impl TryToRustTy for Type { #ident }) } - TypeKind::ObjCSel => { - Ok(quote! { - objc::runtime::Sel - }) - } - TypeKind::ObjCId | - TypeKind::ObjCInterface(..) => Ok(quote! { + TypeKind::ObjCSel => Ok(quote! { + objc::runtime::Sel + }), + TypeKind::ObjCId | TypeKind::ObjCInterface(..) => Ok(quote! { id }), ref u @ TypeKind::UnresolvedTypeRef(..) => { @@ -3227,9 +3266,9 @@ impl TryToOpaque for TemplateInstantiation { ctx: &BindgenContext, item: &Item, ) -> error::Result<Layout> { - item.expect_type().layout(ctx).ok_or( - error::Error::NoLayoutForOpaqueBlob, - ) + item.expect_type() + .layout(ctx) + .ok_or(error::Error::NoLayoutForOpaqueBlob) } } @@ -3245,23 +3284,25 @@ impl TryToRustTy for TemplateInstantiation { return Err(error::Error::InstantiationOfOpaqueType); } - let def = self.template_definition() + let def = self + .template_definition() .into_resolver() .through_type_refs() .resolve(ctx); let mut ty = quote! {}; let def_path = def.namespace_aware_canonical_path(ctx); - ty.append_separated(def_path.into_iter().map(|p| ctx.rust_ident(p)), quote!(::)); + ty.append_separated( + def_path.into_iter().map(|p| ctx.rust_ident(p)), + quote!(::), + ); let def_params = def.self_template_params(ctx); if def_params.is_empty() { // This can happen if we generated an opaque type for a partial // template specialization, and we've hit an instantiation of // that partial specialization. - extra_assert!( - def.is_opaque(ctx, &()) - ); + extra_assert!(def.is_opaque(ctx, &())); return Err(error::Error::InstantiationOfOpaqueType); } @@ -3273,11 +3314,12 @@ impl TryToRustTy for TemplateInstantiation { // reconstruct them somehow. We don't have any means of doing // that reconstruction at this time. - let template_args = self.template_arguments() + let template_args = self + .template_arguments() .iter() .zip(def_params.iter()) - // Only pass type arguments for the type parameters that - // the def uses. + // Only pass type arguments for the type parameters that + // the def uses. .filter(|&(_, param)| ctx.uses_template_parameter(def.id(), *param)) .map(|(arg, _)| { let arg = arg.into_resolver().through_type_refs().resolve(ctx); @@ -3315,11 +3357,9 @@ impl TryToRustTy for FunctionSig { warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target"); Ok(proc_macro2::TokenStream::new()) } - _ => { - Ok(quote! { - unsafe extern #abi fn ( #( #arguments ),* ) #ret - }) - } + _ => Ok(quote! { + unsafe extern #abi fn ( #( #arguments ),* ) #ret + }), } } } @@ -3346,10 +3386,12 @@ impl CodeGenerator for Function { // Pure virtual methods have no actual symbol, so we can't generate // something meaningful for them. match self.kind() { - FunctionKind::Method(ref method_kind) if method_kind.is_pure_virtual() => { + FunctionKind::Method(ref method_kind) + if method_kind.is_pure_virtual() => + { return; } - _ => {}, + _ => {} } // Similar to static member variables in a class template, we can't @@ -3387,7 +3429,9 @@ impl CodeGenerator for Function { let mut attributes = vec![]; - if signature.must_use() && ctx.options().rust_features().must_use_function { + if signature.must_use() && + ctx.options().rust_features().must_use_function + { attributes.push(attributes::must_use()); } @@ -3414,9 +3458,7 @@ impl CodeGenerator for Function { Abi::Unknown(unknown_abi) => { panic!( "Invalid or unknown abi {:?} for function {:?} ({:?})", - unknown_abi, - canonical_name, - self + unknown_abi, canonical_name, self ); } abi => abi, @@ -3440,7 +3482,6 @@ impl CodeGenerator for Function { } } - fn objc_method_codegen( ctx: &BindgenContext, method: &ObjCMethod, @@ -3458,8 +3499,7 @@ fn objc_method_codegen( } } else { let fn_args = fn_args.clone(); - let args = iter::once(quote! { self }) - .chain(fn_args.into_iter()); + let args = iter::once(quote! { self }).chain(fn_args.into_iter()); quote! { ( #( #args ),* ) #fn_ret } @@ -3471,7 +3511,10 @@ fn objc_method_codegen( let class_name = class_name .expect("Generating a class method without class name?") .to_owned(); - let expect_msg = proc_macro2::Literal::string(&format!("Couldn't find {}", class_name)); + let expect_msg = proc_macro2::Literal::string(&format!( + "Couldn't find {}", + class_name + )); quote! { msg_send!(objc::runtime::Class::get(#class_name).expect(#expect_msg), #methods_and_args) } @@ -3481,7 +3524,8 @@ fn objc_method_codegen( } }; - let method_name = ctx.rust_ident(format!("{}{}", prefix, method.rust_name())); + let method_name = + ctx.rust_ident(format!("{}{}", prefix, method.rust_name())); ( quote! { @@ -3491,7 +3535,7 @@ fn objc_method_codegen( }, quote! { unsafe fn #method_name #sig ; - } + }, ) } @@ -3516,12 +3560,8 @@ impl CodeGenerator for ObjCInterface { trait_items.push(trait_item) } - let instance_method_names: Vec<_> = self.methods() - .iter() - .map({ - |m| m.rust_name() - }) - .collect(); + let instance_method_names: Vec<_> = + self.methods().iter().map({ |m| m.rust_name() }).collect(); for class_method in self.class_methods() { let ambiquity = @@ -3560,7 +3600,9 @@ impl CodeGenerator for ObjCInterface { } } -pub(crate) fn codegen(context: BindgenContext) -> (Vec<proc_macro2::TokenStream>, BindgenOptions) { +pub(crate) fn codegen( + context: BindgenContext, +) -> (Vec<proc_macro2::TokenStream>, BindgenOptions) { context.gen(|context| { let _t = context.timer("codegen"); let counter = Cell::new(0); @@ -3579,20 +3621,26 @@ pub(crate) fn codegen(context: BindgenContext) -> (Vec<proc_macro2::TokenStream> if let Some(path) = context.options().emit_ir_graphviz.as_ref() { match dot::write_dot_file(context, path) { - Ok(()) => info!("Your dot file was generated successfully into: {}", path), + Ok(()) => info!( + "Your dot file was generated successfully into: {}", + path + ), Err(e) => error!("{}", e), } } - context.resolve_item(context.root_module()) - .codegen(context, &mut result, &()); + context.resolve_item(context.root_module()).codegen( + context, + &mut result, + &(), + ); result.items }) } mod utils { - use super::{ToRustTyOrOpaque, error}; + use super::{error, ToRustTyOrOpaque}; use ir::context::BindgenContext; use ir::function::{Abi, FunctionSig}; use ir::item::{Item, ItemCanonicalPath}; @@ -3604,7 +3652,7 @@ mod utils { pub fn prepend_bitfield_unit_type( ctx: &BindgenContext, - result: &mut Vec<proc_macro2::TokenStream> + result: &mut Vec<proc_macro2::TokenStream>, ) { let bitfield_unit_src = include_str!("./bitfield_unit.rs"); let bitfield_unit_src = if ctx.options().rust_features().min_const_fn { @@ -3612,7 +3660,8 @@ mod utils { } else { Cow::Owned(bitfield_unit_src.replace("const fn ", "fn ")) }; - let bitfield_unit_type = proc_macro2::TokenStream::from_str(&bitfield_unit_src).unwrap(); + let bitfield_unit_type = + proc_macro2::TokenStream::from_str(&bitfield_unit_src).unwrap(); let bitfield_unit_type = quote!(#bitfield_unit_type); let items = vec![bitfield_unit_type]; @@ -3673,9 +3722,9 @@ mod utils { // If the target supports `const fn`, declare eligible functions // as `const fn` else just `fn`. let const_fn = if ctx.options().rust_features().min_const_fn { - quote!{ const fn } + quote! { const fn } } else { - quote!{ fn } + quote! { fn } }; // TODO(emilio): The fmt::Debug impl could be way nicer with @@ -3757,15 +3806,17 @@ mod utils { } }; - let items = vec![union_field_decl, - union_field_impl, - union_field_default_impl, - union_field_clone_impl, - union_field_copy_impl, - union_field_debug_impl, - union_field_hash_impl, - union_field_partialeq_impl, - union_field_eq_impl]; + let items = vec![ + union_field_decl, + union_field_impl, + union_field_default_impl, + union_field_clone_impl, + union_field_copy_impl, + union_field_debug_impl, + union_field_hash_impl, + union_field_partialeq_impl, + union_field_eq_impl, + ]; let old_items = mem::replace(result, items); result.extend(old_items.into_iter()); @@ -3780,9 +3831,9 @@ mod utils { // If the target supports `const fn`, declare eligible functions // as `const fn` else just `fn`. let const_fn = if ctx.options().rust_features().min_const_fn { - quote!{ const fn } + quote! { const fn } } else { - quote!{ fn } + quote! { fn } }; let incomplete_array_decl = quote! { @@ -3839,18 +3890,18 @@ mod utils { } }; - let items = vec![incomplete_array_decl, - incomplete_array_impl, - incomplete_array_debug_impl, - incomplete_array_clone_impl]; + let items = vec![ + incomplete_array_decl, + incomplete_array_impl, + incomplete_array_debug_impl, + incomplete_array_clone_impl, + ]; let old_items = mem::replace(result, items); result.extend(old_items.into_iter()); } - pub fn prepend_complex_type( - result: &mut Vec<proc_macro2::TokenStream>, - ) { + pub fn prepend_complex_type(result: &mut Vec<proc_macro2::TokenStream>) { let complex_type = quote! { #[derive(PartialEq, Copy, Clone, Hash, Debug, Default)] #[repr(C)] @@ -3870,12 +3921,16 @@ mod utils { ctx: &BindgenContext, ) -> error::Result<proc_macro2::TokenStream> { let path = item.namespace_aware_canonical_path(ctx); - let tokens = proc_macro2::TokenStream::from_str(&path.join("::")).unwrap(); + let tokens = + proc_macro2::TokenStream::from_str(&path.join("::")).unwrap(); Ok(tokens) } - fn primitive_ty(ctx: &BindgenContext, name: &str) -> proc_macro2::TokenStream { + fn primitive_ty( + ctx: &BindgenContext, + name: &str, + ) -> proc_macro2::TokenStream { let ident = ctx.rust_ident_raw(name); quote! { #ident @@ -3911,7 +3966,7 @@ mod utils { ) -> proc_macro2::TokenStream { let return_item = ctx.resolve_item(sig.return_type()); if let TypeKind::Void = *return_item.kind().expect_type().kind() { - quote! { } + quote! {} } else { let ret_ty = return_item.to_rust_ty_or_opaque(ctx, &()); quote! { @@ -3927,58 +3982,63 @@ mod utils { use super::ToPtr; let mut unnamed_arguments = 0; - let mut args = sig.argument_types().iter().map(|&(ref name, ty)| { - let arg_item = ctx.resolve_item(ty); - let arg_ty = arg_item.kind().expect_type(); - - // From the C90 standard[1]: - // - // A declaration of a parameter as "array of type" shall be - // adjusted to "qualified pointer to type", where the type - // qualifiers (if any) are those specified within the [ and ] of - // the array type derivation. - // - // [1]: http://c0x.coding-guidelines.com/6.7.5.3.html - let arg_ty = match *arg_ty.canonical_type(ctx).kind() { - TypeKind::Array(t, _) => { - let stream = if ctx.options().array_pointers_in_arguments { - arg_ty.to_rust_ty_or_opaque(ctx, &arg_item) - } else { - t.to_rust_ty_or_opaque(ctx, &()) - }; - stream.to_ptr(ctx.resolve_type(t).is_const()) - } - TypeKind::Pointer(inner) => { - let inner = ctx.resolve_item(inner); - let inner_ty = inner.expect_type(); - if let TypeKind::ObjCInterface(_) = *inner_ty.canonical_type(ctx).kind() { - quote! { - id + let mut args = sig + .argument_types() + .iter() + .map(|&(ref name, ty)| { + let arg_item = ctx.resolve_item(ty); + let arg_ty = arg_item.kind().expect_type(); + + // From the C90 standard[1]: + // + // A declaration of a parameter as "array of type" shall be + // adjusted to "qualified pointer to type", where the type + // qualifiers (if any) are those specified within the [ and ] of + // the array type derivation. + // + // [1]: http://c0x.coding-guidelines.com/6.7.5.3.html + let arg_ty = match *arg_ty.canonical_type(ctx).kind() { + TypeKind::Array(t, _) => { + let stream = + if ctx.options().array_pointers_in_arguments { + arg_ty.to_rust_ty_or_opaque(ctx, &arg_item) + } else { + t.to_rust_ty_or_opaque(ctx, &()) + }; + stream.to_ptr(ctx.resolve_type(t).is_const()) + } + TypeKind::Pointer(inner) => { + let inner = ctx.resolve_item(inner); + let inner_ty = inner.expect_type(); + if let TypeKind::ObjCInterface(_) = + *inner_ty.canonical_type(ctx).kind() + { + quote! { + id + } + } else { + arg_item.to_rust_ty_or_opaque(ctx, &()) } - } else { - arg_item.to_rust_ty_or_opaque(ctx, &()) } - }, - _ => { - arg_item.to_rust_ty_or_opaque(ctx, &()) - } - }; + _ => arg_item.to_rust_ty_or_opaque(ctx, &()), + }; - let arg_name = match *name { - Some(ref name) => ctx.rust_mangle(name).into_owned(), - None => { - unnamed_arguments += 1; - format!("arg{}", unnamed_arguments) - } - }; + let arg_name = match *name { + Some(ref name) => ctx.rust_mangle(name).into_owned(), + None => { + unnamed_arguments += 1; + format!("arg{}", unnamed_arguments) + } + }; - assert!(!arg_name.is_empty()); - let arg_name = ctx.rust_ident(arg_name); + assert!(!arg_name.is_empty()); + let arg_name = ctx.rust_ident(arg_name); - quote! { - #arg_name : #arg_ty - } - }).collect::<Vec<_>>(); + quote! { + #arg_name : #arg_ty + } + }) + .collect::<Vec<_>>(); if sig.is_variadic() { args.push(quote! { ... }) @@ -3998,11 +4058,12 @@ mod utils { }); let return_item = ctx.resolve_item(sig.return_type()); - let ret_ty = if let TypeKind::Void = *return_item.kind().expect_type().kind() { - quote! { () } - } else { - return_item.to_rust_ty_or_opaque(ctx, &()) - }; + let ret_ty = + if let TypeKind::Void = *return_item.kind().expect_type().kind() { + quote! { () } + } else { + return_item.to_rust_ty_or_opaque(ctx, &()) + }; quote! { *const ::block::Block<(#(#args,)*), #ret_ty> |