Skip to content

Commit

Permalink
Adding where clauses
Browse files Browse the repository at this point in the history
  • Loading branch information
adetaylor committed Feb 5, 2021
1 parent ed09d13 commit 8bb23ad
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 31 deletions.
62 changes: 37 additions & 25 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1861,7 +1861,6 @@ impl CodeGenerator for CompInfo {
}

let mut generic_param_names = vec![];
let mut generic_params = vec![];

let used_dependent_qualified_types =
item.used_dependent_qualified_types(ctx);
Expand All @@ -1887,46 +1886,39 @@ impl CodeGenerator for CompInfo {
}
}

let empty = vec![];
let mut where_constraints: std::collections::HashMap<
Ident,
Vec<Ident>,
> = std::collections::HashMap::new();
for (idx, ty) in item.used_template_params(ctx).iter().enumerate() {
let param = ctx.resolve_type(*ty);
let dependent_qualified_type_field_names =
dependent_qualified_types_by_param.get(ty).unwrap_or(&empty);

let name = param.name().unwrap();
let ident = ctx.rust_ident(name);
generic_param_names.push(ident.clone());
let mut this_generic = quote! {
#ident
};
for (count, field_name) in
dependent_qualified_type_field_names.into_iter().enumerate()
if let Some(dependent_qualified_type_field_names) =
dependent_qualified_types_by_param.get(ty)
{
let trait_name = ctx.inner_type_trait_ident(field_name);
this_generic.extend(if count == 0 {
quote! {
: #trait_name
}
} else {
quote! {
+ #trait_name
}
});
where_constraints.entry(ident.clone()).or_default().extend(
dependent_qualified_type_field_names.into_iter().map(
|field_name| ctx.inner_type_trait_ident(field_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>
> ,
});
generic_params.push(this_generic);
}

let generics = if !generic_params.is_empty() {
let generics = if !generic_param_names.is_empty() {
let generic_param_names = generic_param_names.clone();
quote! {
< #( #generic_params ),* >
< #( #generic_param_names ),* >
}
} else {
quote! {}
Expand Down Expand Up @@ -2013,8 +2005,28 @@ impl CodeGenerator for CompInfo {
}
};

let mut where_constraints_ts = quote! {};
if !where_constraints.is_empty() {
for (i, (k, traits)) in where_constraints.into_iter().enumerate() {
let prefix = if i == 0 {
quote! { where }
} else {
quote! { , }
};
where_constraints_ts.extend(quote! { #prefix #k });
for (j, v) in traits.into_iter().enumerate() {
let sep = if j == 0 {
quote! {:}
} else {
quote! {+}
};
where_constraints_ts.extend(quote! { #sep #v });
}
}
}

tokens.append_all(quote! {
#generics {
#generics #where_constraints_ts {
#( #fields )*
}
});
Expand Down
5 changes: 4 additions & 1 deletion tests/expectations/tests/inner_type_complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ fn bindgen_test_layout_InnerType() {
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct Container<ContainedType: __bindgen_has_inner_type_related_type> {
pub struct Container<ContainedType>
where
ContainedType: __bindgen_has_inner_type_related_type,
{
pub contents_: Container_content_ty<ContainedType>,
pub _phantom_0:
::std::marker::PhantomData<::std::cell::UnsafeCell<ContainedType>>,
Expand Down
5 changes: 4 additions & 1 deletion tests/expectations/tests/inner_type_simpler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ fn bindgen_test_layout_InnerType() {
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct Container<ContainedType: __bindgen_has_inner_type_related_type> {
pub struct Container<ContainedType>
where
ContainedType: __bindgen_has_inner_type_related_type,
{
pub contents_:
<ContainedType as __bindgen_has_inner_type_related_type>::related_type,
pub _phantom_0:
Expand Down
5 changes: 4 additions & 1 deletion tests/expectations/tests/inner_type_two.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ fn bindgen_test_layout_InnerTypeB() {
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct Container<ContainedType: __bindgen_has_inner_type_related_type> {
pub struct Container<ContainedType>
where
ContainedType: __bindgen_has_inner_type_related_type,
{
pub contents_: Container_content_ty<ContainedType>,
pub _phantom_0:
::std::marker::PhantomData<::std::cell::UnsafeCell<ContainedType>>,
Expand Down
10 changes: 7 additions & 3 deletions tests/expectations/tests/issue-544-stylo-creduce-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo {
pub struct Foo<T>
where
T: __bindgen_has_inner_type_Associated,
{
pub member: Foo_SecondAlias,
pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
}
pub type Foo_FirstAlias<T> =
<T as __bindgen_has_inner_type_Associated>::Associated;
pub type Foo_SecondAlias = Foo;
impl Default for Foo {
pub type Foo_SecondAlias = Foo<Foo_FirstAlias>;
impl<T> Default for Foo<T> {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
Expand Down

0 comments on commit 8bb23ad

Please sign in to comment.