From ac3e4e476f67411177e73e80f0e932aaba5a6593 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sun, 8 Apr 2018 18:25:41 -0400 Subject: [PATCH 1/5] Avoid new validation in proc-macro2 Evidently, we run afoul of this. --- Cargo.toml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a9f2bdc6cf..c15674c981 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,9 @@ peeking_take_while = "0.1.2" quote = { version = "0.5", default-features = false } regex = "0.2" which = "1.0.2" -proc-macro2 = { version = "0.3.2", default-features = false } +# New validation in 0.3.6 breaks bindgen-integration: +# https://github.com/alexcrichton/proc-macro2/commit/489c642. +proc-macro2 = { version = "0.3.2, < 0.3.6", default-features = false } [dependencies.env_logger] optional = true From cd37739d4e7d193301e94d45c7f1448118cbc7fd Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 7 Apr 2018 00:12:24 -0400 Subject: [PATCH 2/5] TemplateParameters.self_template_params doesn't return Option --- src/codegen/mod.rs | 22 ++++++++-------- src/ir/analysis/derive_copy.rs | 2 +- src/ir/analysis/template_params.rs | 4 +-- src/ir/comp.rs | 8 ++---- src/ir/context.rs | 9 +++---- src/ir/item.rs | 10 ++++---- src/ir/template.rs | 40 +++++++++++++++--------------- src/ir/ty.rs | 8 +++--- 8 files changed, 47 insertions(+), 56 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 6483412ed5..34e87d8973 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -3138,18 +3138,16 @@ impl TryToRustTy for TemplateInstantiation { let def_path = def.namespace_aware_canonical_path(ctx); ty.append_separated(def_path.into_iter().map(|p| ctx.rust_ident(p)), Term::new("::", Span::call_site())); - let def_params = match def.self_template_params(ctx) { - Some(params) => params, - None => { - // 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, &()) - ); - return Err(error::Error::InstantiationOfOpaqueType); - } - }; + 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, &()) + ); + return Err(error::Error::InstantiationOfOpaqueType); + } // TODO: If the definition type is a template class/struct // definition's member template definition, it could rely on diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index 69725ead49..59eb469b23 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -246,7 +246,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { } // https://github.com/rust-lang/rust/issues/36640 - if info.self_template_params(self.ctx).is_some() || + if !info.self_template_params(self.ctx).is_empty() || item.used_template_params(self.ctx).is_some() { trace!( diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs index 00504aa40e..b326e6b58b 100644 --- a/src/ir/analysis/template_params.rs +++ b/src/ir/analysis/template_params.rs @@ -275,7 +275,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> { 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![]); + let params = decl.self_template_params(self.ctx); debug_assert!(this_id != instantiation.template_definition()); let used_by_def = self.used @@ -419,7 +419,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // template parameters, there is a single exception: // opaque templates. Hence the unwrap_or. let params = - decl.self_template_params(ctx).unwrap_or(vec![]); + decl.self_template_params(ctx); for (arg, param) in args.iter().zip(params.iter()) { let arg = arg.into_resolver() diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 8c2be498e9..7ec2add9f1 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1669,12 +1669,8 @@ impl TemplateParameters for CompInfo { fn self_template_params( &self, _ctx: &BindgenContext, - ) -> Option> { - if self.template_params.is_empty() { - None - } else { - Some(self.template_params.clone()) - } + ) -> Vec { + self.template_params.clone() } } diff --git a/src/ir/context.rs b/src/ir/context.rs index 58a90ba6bb..dbe1a64a0e 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1366,10 +1366,7 @@ impl BindgenContext { let mut used_params = HashMap::new(); for &id in self.whitelisted_items() { used_params.entry(id).or_insert( - id.self_template_params(self).map_or( - Default::default(), - |params| params.into_iter().map(|p| p.into()).collect(), - ), + id.self_template_params(self).into_iter().map(|p| p.into()).collect() ); } self.used_template_parameters = Some(used_params); @@ -2647,10 +2644,10 @@ impl TemplateParameters for PartialType { fn self_template_params( &self, _ctx: &BindgenContext, - ) -> Option> { + ) -> Vec { // Maybe at some point we will eagerly parse named types, but for now we // don't and this information is unavailable. - None + vec![] } fn num_self_template_params(&self, _ctx: &BindgenContext) -> Option { diff --git a/src/ir/item.rs b/src/ir/item.rs index 2b3c1b8c41..1cb1d5f9ff 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -1112,8 +1112,8 @@ where fn self_template_params( &self, ctx: &BindgenContext, - ) -> Option> { - ctx.resolve_item_fallible(*self).and_then(|item| { + ) -> Vec { + ctx.resolve_item_fallible(*self).map_or(vec![], |item| { item.self_template_params(ctx) }) } @@ -1123,7 +1123,7 @@ impl TemplateParameters for Item { fn self_template_params( &self, ctx: &BindgenContext, - ) -> Option> { + ) -> Vec { self.kind.self_template_params(ctx) } } @@ -1132,7 +1132,7 @@ impl TemplateParameters for ItemKind { fn self_template_params( &self, ctx: &BindgenContext, - ) -> Option> { + ) -> Vec { match *self { ItemKind::Type(ref ty) => ty.self_template_params(ctx), // If we start emitting bindings to explicitly instantiated @@ -1140,7 +1140,7 @@ impl TemplateParameters for ItemKind { // template params. ItemKind::Function(_) | ItemKind::Module(_) | - ItemKind::Var(_) => None, + ItemKind::Var(_) => vec![], } } } diff --git a/src/ir/template.rs b/src/ir/template.rs index 11a799f4f6..b5094fc65f 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -81,12 +81,12 @@ use parse::ClangItemParser; /// +------+----------------------+--------------------------+------------------------+---- /// |Decl. | self_template_params | num_self_template_params | all_template_parameters| ... /// +------+----------------------+--------------------------+------------------------+---- -/// |Foo | Some([T, U]) | Some(2) | Some([T, U]) | ... -/// |Bar | Some([V]) | Some(1) | Some([T, U, V]) | ... -/// |Inner | None | None | Some([T, U]) | ... -/// |Lol | Some([W]) | Some(1) | Some([T, U, W]) | ... -/// |Wtf | Some([X]) | Some(1) | Some([T, U, X]) | ... -/// |Qux | None | None | None | ... +/// |Foo | [T, U] | Some(2) | Some([T, U]) | ... +/// |Bar | [V] | Some(1) | Some([T, U, V]) | ... +/// |Inner | [] | None | Some([T, U]) | ... +/// |Lol | [W] | Some(1) | Some([T, U, W]) | ... +/// |Wtf | [X] | Some(1) | Some([T, U, X]) | ... +/// |Qux | [] | None | None | ... /// +------+----------------------+--------------------------+------------------------+---- /// /// ----+------+-----+----------------------+ @@ -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>; + -> Vec; /// Get the number of free template parameters this template declaration /// has. @@ -119,7 +119,12 @@ pub trait TemplateParameters { /// partial information about the template declaration, such as when we are /// in the middle of parsing it. fn num_self_template_params(&self, ctx: &BindgenContext) -> Option { - self.self_template_params(ctx).map(|params| params.len()) + let len = self.self_template_params(ctx).len(); + if len > 0 { + Some(len) + } else { + None + } } /// Get the complete set of template parameters that can affect this @@ -140,19 +145,14 @@ pub trait TemplateParameters { where Self: ItemAncestors, { - let each_self_params: Vec> = self.ancestors(ctx) - .filter_map(|id| id.self_template_params(ctx)) - .collect(); - if each_self_params.is_empty() { - None + let ancestors: Vec<_> = self.ancestors(ctx).collect(); + let all_template_params: Vec<_> = ancestors.into_iter().rev().flat_map(|id| { + id.self_template_params(ctx).into_iter() + }).collect(); + if all_template_params.len() > 0 { + Some(all_template_params) } else { - Some( - each_self_params - .into_iter() - .rev() - .flat_map(|params| params) - .collect(), - ) + None } } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index b42f44240c..b5c78c16b5 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -540,7 +540,7 @@ impl TemplateParameters for Type { fn self_template_params( &self, ctx: &BindgenContext, - ) -> Option> { + ) -> Vec { self.kind.self_template_params(ctx) } } @@ -549,13 +549,13 @@ impl TemplateParameters for TypeKind { fn self_template_params( &self, ctx: &BindgenContext, - ) -> Option> { + ) -> Vec { match *self { TypeKind::ResolvedTypeRef(id) => { ctx.resolve_type(id).self_template_params(ctx) } TypeKind::Comp(ref comp) => comp.self_template_params(ctx), - TypeKind::TemplateAlias(_, ref args) => Some(args.clone()), + TypeKind::TemplateAlias(_, ref args) => args.clone(), TypeKind::Opaque | TypeKind::TemplateInstantiation(..) | @@ -575,7 +575,7 @@ impl TemplateParameters for TypeKind { TypeKind::Alias(_) | TypeKind::ObjCId | TypeKind::ObjCSel | - TypeKind::ObjCInterface(_) => None, + TypeKind::ObjCInterface(_) => vec![], } } } From 85b1a3a9f19b57c228b4cda5915d2219e15e8533 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 7 Apr 2018 07:03:30 -0400 Subject: [PATCH 3/5] TemplateParameters.num_self_template_params doesn't return Option --- src/ir/context.rs | 63 +++++++++++++++++++++++----------------------- src/ir/template.rs | 26 ++++++------------- 2 files changed, 39 insertions(+), 50 deletions(-) diff --git a/src/ir/context.rs b/src/ir/context.rs index dbe1a64a0e..bbcc569815 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -1549,15 +1549,16 @@ impl BindgenContext { .and_then(|canon_decl| { self.get_resolved_type(&canon_decl).and_then( |template_decl_id| { - template_decl_id.num_self_template_params(self).map( - |num_params| { - ( - *canon_decl.cursor(), - template_decl_id.into(), - num_params, - ) - }, - ) + let num_params = template_decl_id.num_self_template_params(self); + if num_params == 0 { + None + } else { + Some(( + *canon_decl.cursor(), + template_decl_id.into(), + num_params, + )) + } }, ) }) @@ -1578,15 +1579,16 @@ impl BindgenContext { .cloned() }) .and_then(|template_decl| { - template_decl.num_self_template_params(self).map( - |num_template_params| { - ( - *template_decl.decl(), - template_decl.id(), - num_template_params, - ) - }, - ) + let num_template_params = template_decl.num_self_template_params(self); + if num_template_params == 0 { + None + } else { + Some(( + *template_decl.decl(), + template_decl.id(), + num_template_params, + )) + } }) }) } @@ -1633,17 +1635,14 @@ impl BindgenContext { ) -> Option { use clang_sys; - let num_expected_args = match self.resolve_type(template) - .num_self_template_params(self) { - Some(n) => n, - None => { - warn!( - "Tried to instantiate a template for which we could not \ - determine any template parameters" - ); - return None; - } - }; + let num_expected_args = self.resolve_type(template).num_self_template_params(self); + if num_expected_args == 0 { + warn!( + "Tried to instantiate a template for which we could not \ + determine any template parameters" + ); + return None; + } let mut args = vec![]; let mut found_const_arg = false; @@ -2650,7 +2649,7 @@ impl TemplateParameters for PartialType { vec![] } - fn num_self_template_params(&self, _ctx: &BindgenContext) -> Option { + fn num_self_template_params(&self, _ctx: &BindgenContext) -> usize { // Wouldn't it be nice if libclang would reliably give us this // information‽ match self.decl().kind() { @@ -2669,9 +2668,9 @@ impl TemplateParameters for PartialType { }; clang_sys::CXChildVisit_Continue }); - Some(num_params) + num_params } - _ => None, + _ => 0, } } } diff --git a/src/ir/template.rs b/src/ir/template.rs index b5094fc65f..71164fd59e 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -81,12 +81,12 @@ use parse::ClangItemParser; /// +------+----------------------+--------------------------+------------------------+---- /// |Decl. | self_template_params | num_self_template_params | all_template_parameters| ... /// +------+----------------------+--------------------------+------------------------+---- -/// |Foo | [T, U] | Some(2) | Some([T, U]) | ... -/// |Bar | [V] | Some(1) | Some([T, U, V]) | ... -/// |Inner | [] | None | Some([T, U]) | ... -/// |Lol | [W] | Some(1) | Some([T, U, W]) | ... -/// |Wtf | [X] | Some(1) | Some([T, U, X]) | ... -/// |Qux | [] | None | None | ... +/// |Foo | [T, U] | 2 | Some([T, U]) | ... +/// |Bar | [V] | 1 | Some([T, U, V]) | ... +/// |Inner | [] | 0 | Some([T, U]) | ... +/// |Lol | [W] | 1 | Some([T, U, W]) | ... +/// |Wtf | [X] | 1 | Some([T, U, X]) | ... +/// |Qux | [] | 0 | None | ... /// +------+----------------------+--------------------------+------------------------+---- /// /// ----+------+-----+----------------------+ @@ -113,18 +113,8 @@ pub trait TemplateParameters { /// Get the number of free template parameters this template declaration /// has. - /// - /// Implementations *may* return `Some` from this method when - /// `template_params` returns `None`. This is useful when we only have - /// partial information about the template declaration, such as when we are - /// in the middle of parsing it. - fn num_self_template_params(&self, ctx: &BindgenContext) -> Option { - let len = self.self_template_params(ctx).len(); - if len > 0 { - Some(len) - } else { - None - } + fn num_self_template_params(&self, ctx: &BindgenContext) -> usize { + self.self_template_params(ctx).len() } /// Get the complete set of template parameters that can affect this From e28cb8a13ecacf0dc4aeab6119ca9fea8d0a1cc9 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 7 Apr 2018 07:21:49 -0400 Subject: [PATCH 4/5] TemplateParameters.all_template_params doesn't return Option --- src/codegen/mod.rs | 14 ++++---------- src/ir/comp.rs | 3 +-- src/ir/template.rs | 39 +++++++++++++++++---------------------- 3 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 34e87d8973..e2a8b33f14 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -479,11 +479,8 @@ impl CodeGenerator for Var { // We can't generate bindings to static variables of templates. The // number of actual variables for a single declaration are open ended // and we don't know what instantiations do or don't exist. - let type_params = item.all_template_params(ctx); - if let Some(params) = type_params { - if !params.is_empty() { - return; - } + if !item.all_template_params(ctx).is_empty() { + return; } let ty = self.ty().to_rust_ty_or_opaque(ctx, &()); @@ -3240,11 +3237,8 @@ impl CodeGenerator for Function { // generate bindings to template functions, because the set of // instantiations is open ended and we have no way of knowing which // monomorphizations actually exist. - let type_params = item.all_template_params(ctx); - if let Some(params) = type_params { - if !params.is_empty() { - return; - } + if !item.all_template_params(ctx).is_empty() { + return; } let name = self.name(); diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 7ec2add9f1..8c52906728 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1681,8 +1681,7 @@ impl Trace for CompInfo { where T: Tracer, { - let params = item.all_template_params(context).unwrap_or(vec![]); - for p in params { + for p in item.all_template_params(context) { tracer.visit_kind(p.into(), EdgeKind::TemplateParameterDefinition); } diff --git a/src/ir/template.rs b/src/ir/template.rs index 71164fd59e..cdea85cf7a 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -81,12 +81,12 @@ use parse::ClangItemParser; /// +------+----------------------+--------------------------+------------------------+---- /// |Decl. | self_template_params | num_self_template_params | all_template_parameters| ... /// +------+----------------------+--------------------------+------------------------+---- -/// |Foo | [T, U] | 2 | Some([T, U]) | ... -/// |Bar | [V] | 1 | Some([T, U, V]) | ... -/// |Inner | [] | 0 | Some([T, U]) | ... -/// |Lol | [W] | 1 | Some([T, U, W]) | ... -/// |Wtf | [X] | 1 | Some([T, U, X]) | ... -/// |Qux | [] | 0 | None | ... +/// |Foo | [T, U] | 2 | [T, U] | ... +/// |Bar | [V] | 1 | [T, U, V] | ... +/// |Inner | [] | 0 | [T, U] | ... +/// |Lol | [W] | 1 | [T, U, W] | ... +/// |Wtf | [X] | 1 | [T, U, X] | ... +/// |Qux | [] | 0 | [] | ... /// +------+----------------------+--------------------------+------------------------+---- /// /// ----+------+-----+----------------------+ @@ -131,19 +131,14 @@ 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) -> Vec where Self: ItemAncestors, { let ancestors: Vec<_> = self.ancestors(ctx).collect(); - let all_template_params: Vec<_> = ancestors.into_iter().rev().flat_map(|id| { + ancestors.into_iter().rev().flat_map(|id| { id.self_template_params(ctx).into_iter() - }).collect(); - if all_template_params.len() > 0 { - Some(all_template_params) - } else { - None - } + }).collect() } /// Get only the set of template parameters that this item uses. This is a @@ -159,14 +154,14 @@ pub trait TemplateParameters { ); let id = *self.as_ref(); - ctx.resolve_item(id).all_template_params(ctx).map( - |all_params| { - all_params - .into_iter() - .filter(|p| ctx.uses_template_parameter(id, *p)) - .collect() - }, - ) + let all_template_params: Vec<_> = ctx.resolve_item(id).all_template_params(ctx); + if all_template_params.len() > 0 { + Some(all_template_params.into_iter() + .filter(|p| ctx.uses_template_parameter(id, *p)) + .collect()) + } else { + None + } } } From 8660c0916fa56de0fce3a0a6d670eb254fcfb42c Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 7 Apr 2018 07:48:23 -0400 Subject: [PATCH 5/5] TemplateParameters.used_template_params doesn't return Option --- src/codegen/mod.rs | 99 +++++++++++++++------------------- src/ir/analysis/derive_copy.rs | 2 +- src/ir/template.rs | 26 ++++----- 3 files changed, 54 insertions(+), 73 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index e2a8b33f14..04e28db238 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -299,16 +299,11 @@ impl AppendImplicitTemplateParams for quote::Tokens { _ => {}, } - if let Some(params) = item.used_template_params(ctx) { - if params.is_empty() { - return; - } - - let params = params.into_iter().map(|p| { - p.try_to_rust_ty(ctx, &()) - .expect("template params cannot fail to be a rust type") - }); - + 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 ),* > }); @@ -633,15 +628,10 @@ impl CodeGenerator for Type { return; } - let mut outer_params = item.used_template_params(ctx) - .and_then(|ps| if ps.is_empty() { - None - } else { - Some(ps) - }); + let mut outer_params = item.used_template_params(ctx); let inner_rust_type = if item.is_opaque(ctx, &()) { - outer_params = None; + outer_params = vec![]; self.to_opaque(ctx, item) } else { // Its possible that we have better layout information than @@ -696,7 +686,7 @@ impl CodeGenerator for Type { 'A'...'Z' | 'a'...'z' | '0'...'9' | ':' | '_' | ' ' => true, _ => false, }) && - outer_params.is_none() && + outer_params.is_empty() && inner_item.expect_type().canonical_type(ctx).is_enum() { tokens.append_all(quote! { @@ -715,25 +705,23 @@ impl CodeGenerator for Type { pub type #rust_name }); - if let Some(params) = outer_params { - 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()) { - warn!( - "Item contained invalid template \ - parameter: {:?}", - item - ); - return; - } - - let params = params.iter() - .map(|p| { - p.try_to_rust_ty(ctx, &()) - .expect("type parameters can always convert to rust ty OK") - }); + 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()) { + warn!( + "Item contained invalid template \ + parameter: {:?}", + item + ); + 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(); + if !params.is_empty() { tokens.append_all(quote! { < #( #params ),* > }); @@ -1415,8 +1403,6 @@ impl CodeGenerator for CompInfo { return; } - let used_template_params = item.used_template_params(ctx); - let ty = item.expect_type(); let layout = ty.layout(ctx); let mut packed = self.is_packed(ctx, &layout); @@ -1598,21 +1584,19 @@ impl CodeGenerator for CompInfo { let mut generic_param_names = vec![]; - if let Some(ref params) = used_template_params { - for (idx, ty) in params.iter().enumerate() { - let param = ctx.resolve_type(*ty); - let name = param.name().unwrap(); - let ident = ctx.rust_ident(name); - generic_param_names.push(ident.clone()); + for (idx, ty) in item.used_template_params(ctx).iter().enumerate() { + let param = ctx.resolve_type(*ty); + let name = param.name().unwrap(); + let ident = ctx.rust_ident(name); + generic_param_names.push(ident.clone()); - let prefix = ctx.trait_prefix(); - let field_name = ctx.rust_ident(format!("_phantom_{}", idx)); - fields.push(quote! { - pub #field_name : ::#prefix::marker::PhantomData< - ::#prefix::cell::UnsafeCell<#ident> - > , - }); - } + let prefix = ctx.trait_prefix(); + let field_name = ctx.rust_ident(format!("_phantom_{}", idx)); + fields.push(quote! { + pub #field_name : ::#prefix::marker::PhantomData< + ::#prefix::cell::UnsafeCell<#ident> + > , + }); } let generics = if !generic_param_names.is_empty() { @@ -1665,11 +1649,13 @@ impl CodeGenerator for CompInfo { ctx.options().derive_default && !self.is_forward_declaration(); } + let all_template_params = item.all_template_params(ctx); + if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() { derives.push("Copy"); if ctx.options().rust_features().builtin_clone_impls || - used_template_params.is_some() + !all_template_params.is_empty() { // FIXME: This requires extra logic if you have a big array in a // templated struct. The reason for this is that the magic: @@ -1751,7 +1737,7 @@ impl CodeGenerator for CompInfo { ); } - if used_template_params.is_none() { + if all_template_params.is_empty() { if !is_opaque { for var in self.inner_vars() { ctx.resolve_item(*var).codegen(ctx, result, &()); @@ -3020,7 +3006,6 @@ impl TryToRustTy for Type { TypeKind::TemplateAlias(..) | TypeKind::Alias(..) => { let template_params = item.used_template_params(ctx) - .unwrap_or(vec![]) .into_iter() .filter(|param| param.is_template_param(ctx, &())) .collect::>(); @@ -3039,9 +3024,9 @@ impl TryToRustTy for Type { } } TypeKind::Comp(ref info) => { - let template_params = item.used_template_params(ctx); + let template_params = item.all_template_params(ctx); if info.has_non_type_template_params() || - (item.is_opaque(ctx, &()) && template_params.is_some()) + (item.is_opaque(ctx, &()) && !template_params.is_empty()) { return self.try_to_opaque(ctx, item); } diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index 59eb469b23..1e8dc8199d 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -247,7 +247,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { // https://github.com/rust-lang/rust/issues/36640 if !info.self_template_params(self.ctx).is_empty() || - item.used_template_params(self.ctx).is_some() + !item.all_template_params(self.ctx).is_empty() { trace!( " comp cannot derive copy because issue 36640" diff --git a/src/ir/template.rs b/src/ir/template.rs index cdea85cf7a..61654fe888 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -92,12 +92,12 @@ use parse::ClangItemParser; /// ----+------+-----+----------------------+ /// ... |Decl. | ... | used_template_params | /// ----+------+-----+----------------------+ -/// ... |Foo | ... | Some([T, U]) | -/// ... |Bar | ... | Some([V]) | -/// ... |Inner | ... | None | -/// ... |Lol | ... | Some([T]) | -/// ... |Wtf | ... | Some([T]) | -/// ... |Qux | ... | None | +/// ... |Foo | ... | [T, U] | +/// ... |Bar | ... | [V] | +/// ... |Inner | ... | [] | +/// ... |Lol | ... | [T] | +/// ... |Wtf | ... | [T] | +/// ... |Qux | ... | [] | /// ----+------+-----+----------------------+ pub trait TemplateParameters { /// Get the set of `ItemId`s that make up this template declaration's free @@ -144,7 +144,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) -> Vec where Self: AsRef, { @@ -154,14 +154,10 @@ pub trait TemplateParameters { ); let id = *self.as_ref(); - let all_template_params: Vec<_> = ctx.resolve_item(id).all_template_params(ctx); - if all_template_params.len() > 0 { - Some(all_template_params.into_iter() - .filter(|p| ctx.uses_template_parameter(id, *p)) - .collect()) - } else { - None - } + ctx.resolve_item(id).all_template_params(ctx) + .into_iter() + .filter(|p| ctx.uses_template_parameter(id, *p)) + .collect() } }