Skip to content

Commit 95c57a1

Browse files
committed
Handle 'dropped template param' in more cases.
1 parent 1a71713 commit 95c57a1

File tree

2 files changed

+47
-13
lines changed

2 files changed

+47
-13
lines changed

src/codegen/helpers.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ pub mod attributes {
9898
#[bindgen_unused_template_param_in_arg_or_return]
9999
}
100100
}
101+
102+
pub fn alias_discards_template_params() -> TokenStream {
103+
quote! {
104+
#[bindgen_unused_template_param]
105+
}
106+
}
101107
}
102108

103109
/// Generates a proper type for a field or type with a given `Layout`, that is,

src/codegen/mod.rs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -830,19 +830,19 @@ impl CodeGenerator for Type {
830830
let mut outer_params = item.used_template_params(ctx);
831831

832832
let is_opaque = item.is_opaque(ctx, &());
833-
let inner_rust_type = if is_opaque {
833+
let (inner_rust_type, inner_annotations) = if is_opaque {
834834
outer_params = vec![];
835-
self.to_opaque(ctx, item)
835+
(self.to_opaque(ctx, item), RustTyAnnotation::None)
836836
} else {
837837
// Its possible that we have better layout information than
838838
// the inner type does, so fall back to an opaque blob based
839839
// on our layout if converting the inner item fails.
840-
let mut inner_ty = inner_item
840+
let (mut inner_ty, inner_annotations) = inner_item
841841
.try_to_rust_ty_or_opaque(ctx, &())
842-
.map(|ty| ty.ignore_annotations())
843-
.unwrap_or_else(|_| self.to_opaque(ctx, item));
842+
.map(|ty| ty.to_outer_type())
843+
.unwrap_or_else(|_| (self.to_opaque(ctx, item), RustTyAnnotation::None));
844844
inner_ty.append_implicit_template_params(ctx, inner_item);
845-
inner_ty
845+
(inner_ty, inner_annotations)
846846
};
847847

848848
{
@@ -875,6 +875,10 @@ impl CodeGenerator for Type {
875875
} else {
876876
quote! {}
877877
};
878+
tokens.append_all(match inner_annotations {
879+
RustTyAnnotation::None | RustTyAnnotation::Reference => quote! {},
880+
RustTyAnnotation::HasUnusedTemplateArgs => attributes::alias_discards_template_params(),
881+
});
878882

879883
let alias_style = if ctx.options().type_alias.matches(&name) {
880884
AliasVariation::TypeAlias
@@ -3489,10 +3493,27 @@ impl RustTy {
34893493
}
34903494
}
34913495

3492-
fn new_reference(ts: proc_macro2::TokenStream) -> Self {
3496+
fn new_reference(ts: proc_macro2::TokenStream, inner: RustTyAnnotation) -> Self {
3497+
let annotation = match inner {
3498+
RustTyAnnotation::HasUnusedTemplateArgs => RustTyAnnotation::HasUnusedTemplateArgs,
3499+
_ => RustTyAnnotation::Reference
3500+
};
34933501
Self {
34943502
ts,
3495-
annotation: RustTyAnnotation::Reference,
3503+
annotation,
3504+
}
3505+
}
3506+
3507+
// We're constructing some outer type composed of an inner type,
3508+
// e.g. a reference to a T - the inner type is T
3509+
fn wraps(ts: proc_macro2::TokenStream, inner: RustTyAnnotation) -> Self {
3510+
let annotation = match inner {
3511+
RustTyAnnotation::HasUnusedTemplateArgs => RustTyAnnotation::HasUnusedTemplateArgs,
3512+
_ => RustTyAnnotation::None
3513+
};
3514+
Self {
3515+
ts,
3516+
annotation,
34963517
}
34973518
}
34983519

@@ -3513,6 +3534,12 @@ impl RustTy {
35133534
self.ts
35143535
}
35153536

3537+
// Use when this is an inner type and will become part of an outer type.
3538+
// Pass the annotation into [wraps]
3539+
fn to_outer_type(self) -> (proc_macro2::TokenStream, RustTyAnnotation) {
3540+
(self.ts, self.annotation)
3541+
}
3542+
35163543
fn to_unannotated_ts(self) -> error::Result<proc_macro2::TokenStream> {
35173544
if matches!(self.annotation, RustTyAnnotation::None) {
35183545
Ok(self.ts)
@@ -3687,20 +3714,20 @@ impl TryToRustTy for Type {
36873714
// Regardless if we can properly represent the inner type, we
36883715
// should always generate a proper pointer here, so use
36893716
// infallible conversion of the inner type.
3690-
let mut ty = inner.to_rust_ty_or_opaque(ctx, &()).ignore_annotations();
3717+
let (mut ty, inner_annotations) = inner.to_rust_ty_or_opaque(ctx, &()).to_outer_type();
36913718
ty.append_implicit_template_params(ctx, inner);
36923719

36933720
// Avoid the first function pointer level, since it's already
36943721
// represented in Rust.
36953722
if inner_ty.canonical_type(ctx).is_function() || is_objc_pointer
36963723
{
3697-
Ok(ty.into())
3724+
Ok(RustTy::wraps(ty, inner_annotations))
36983725
} else {
36993726
let ty_ptr = ty.to_ptr(is_const);
37003727
Ok(if is_reference {
3701-
RustTy::new_reference(ty_ptr)
3728+
RustTy::new_reference(ty_ptr, inner_annotations)
37023729
} else {
3703-
ty_ptr.into()
3730+
RustTy::wraps(ty_ptr, inner_annotations)
37043731
})
37053732
}
37063733
}
@@ -4682,7 +4709,8 @@ pub mod utils {
46824709
} else {
46834710
t.to_rust_ty_or_opaque(ctx, &())
46844711
};
4685-
RustTy::new(rust_ty.ignore_annotations().to_ptr(ctx.resolve_type(t).is_const()))
4712+
let (inner_ty, annotations) = rust_ty.to_outer_type();
4713+
RustTy::wraps(inner_ty.to_ptr(ctx.resolve_type(t).is_const()), annotations)
46864714
}
46874715
TypeKind::Pointer(inner) => {
46884716
let inner = ctx.resolve_item(inner);

0 commit comments

Comments
 (0)