Skip to content

Commit e0966f7

Browse files
committed
Fill in elided lifetimes on AssertUnpin and AssertSized
1 parent 3d14230 commit e0966f7

File tree

2 files changed

+50
-12
lines changed

2 files changed

+50
-12
lines changed

macro/src/expand.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fn expand(ffi: Module, doc: Doc, attrs: OtherAttrs, apis: &[Api], types: &Types)
5353
for api in apis {
5454
if let Api::RustType(ety) = api {
5555
expanded.extend(expand_rust_type_import(ety));
56-
hidden.extend(expand_rust_type_assert_unpin(ety));
56+
hidden.extend(expand_rust_type_assert_unpin(ety, types));
5757
}
5858
}
5959

@@ -70,15 +70,15 @@ fn expand(ffi: Module, doc: Doc, attrs: OtherAttrs, apis: &[Api], types: &Types)
7070
let ident = &ety.name.rust;
7171
if !types.structs.contains_key(ident) && !types.enums.contains_key(ident) {
7272
expanded.extend(expand_cxx_type(ety));
73-
hidden.extend(expand_cxx_type_assert_pinned(ety));
73+
hidden.extend(expand_cxx_type_assert_pinned(ety, types));
7474
}
7575
}
7676
Api::CxxFunction(efn) => {
7777
expanded.extend(expand_cxx_function_shim(efn, types));
7878
}
7979
Api::RustType(ety) => {
8080
expanded.extend(expand_rust_type_impl(ety));
81-
hidden.extend(expand_rust_type_layout(ety));
81+
hidden.extend(expand_rust_type_layout(ety, types));
8282
}
8383
Api::RustFunction(efn) => hidden.extend(expand_rust_function_shim(efn, types)),
8484
Api::TypeAlias(alias) => {
@@ -396,10 +396,13 @@ fn expand_cxx_type(ety: &ExternType) -> TokenStream {
396396
}
397397
}
398398

399-
fn expand_cxx_type_assert_pinned(ety: &ExternType) -> TokenStream {
399+
fn expand_cxx_type_assert_pinned(ety: &ExternType, types: &Types) -> TokenStream {
400400
let ident = &ety.name.rust;
401401
let infer = Token![_](ident.span());
402402

403+
let resolve = types.resolve(ident);
404+
let lifetimes = resolve.generics.to_underscore_lifetimes();
405+
403406
quote! {
404407
let _: fn() = {
405408
// Derived from https://github.com/nvzqz/static-assertions-rs.
@@ -424,7 +427,7 @@ fn expand_cxx_type_assert_pinned(ety: &ExternType) -> TokenStream {
424427
// `_` can be resolved and this can compile. Fails to compile if
425428
// user has added a manual Unpin impl for their opaque C++ type as
426429
// then `__AmbiguousIfImpl<__Invalid>` also exists.
427-
<#ident as __AmbiguousIfImpl<#infer>>::infer
430+
<#ident #lifetimes as __AmbiguousIfImpl<#infer>>::infer
428431
};
429432
}
430433
}
@@ -833,21 +836,25 @@ fn expand_rust_type_impl(ety: &ExternType) -> TokenStream {
833836
impls
834837
}
835838

836-
fn expand_rust_type_assert_unpin(ety: &ExternType) -> TokenStream {
839+
fn expand_rust_type_assert_unpin(ety: &ExternType, types: &Types) -> TokenStream {
837840
let ident = &ety.name.rust;
838841
let begin_span = Token![::](ety.type_token.span);
839842
let unpin = quote_spanned! {ety.semi_token.span=>
840843
#begin_span cxx::core::marker::Unpin
841844
};
845+
846+
let resolve = types.resolve(ident);
847+
let lifetimes = resolve.generics.to_underscore_lifetimes();
848+
842849
quote_spanned! {ident.span()=>
843850
let _ = {
844851
fn __AssertUnpin<T: ?::cxx::core::marker::Sized + #unpin>() {}
845-
__AssertUnpin::<#ident>
852+
__AssertUnpin::<#ident #lifetimes>
846853
};
847854
}
848855
}
849856

850-
fn expand_rust_type_layout(ety: &ExternType) -> TokenStream {
857+
fn expand_rust_type_layout(ety: &ExternType, types: &Types) -> TokenStream {
851858
// Rustc will render as follows if not sized:
852859
//
853860
// type TheirType;
@@ -868,6 +875,9 @@ fn expand_rust_type_layout(ety: &ExternType) -> TokenStream {
868875
let local_sizeof = format_ident!("__sizeof_{}", ety.name.rust);
869876
let local_alignof = format_ident!("__alignof_{}", ety.name.rust);
870877

878+
let resolve = types.resolve(ident);
879+
let lifetimes = resolve.generics.to_underscore_lifetimes();
880+
871881
quote_spanned! {ident.span()=>
872882
{
873883
#[doc(hidden)]
@@ -877,12 +887,12 @@ fn expand_rust_type_layout(ety: &ExternType) -> TokenStream {
877887
#[doc(hidden)]
878888
#[export_name = #link_sizeof]
879889
extern "C" fn #local_sizeof() -> usize {
880-
__AssertSized::<#ident>().size()
890+
__AssertSized::<#ident #lifetimes>().size()
881891
}
882892
#[doc(hidden)]
883893
#[export_name = #link_alignof]
884894
extern "C" fn #local_alignof() -> usize {
885-
__AssertSized::<#ident>().align()
895+
__AssertSized::<#ident #lifetimes>().align()
886896
}
887897
}
888898
}

macro/src/generics.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::syntax::instantiate::NamedImplKey;
22
use crate::syntax::resolve::Resolution;
3-
use crate::syntax::Impl;
3+
use crate::syntax::{Impl, Lifetimes};
44
use proc_macro2::TokenStream;
55
use quote::ToTokens;
6-
use syn::Token;
6+
use syn::{Lifetime, Token};
77

88
pub struct ImplGenerics<'a> {
99
explicit_impl: Option<&'a Impl>,
@@ -61,3 +61,31 @@ impl<'a> ToTokens for TyGenerics<'a> {
6161
}
6262
}
6363
}
64+
65+
pub struct UnderscoreLifetimes<'a> {
66+
generics: &'a Lifetimes,
67+
}
68+
69+
impl Lifetimes {
70+
pub fn to_underscore_lifetimes(&self) -> UnderscoreLifetimes {
71+
UnderscoreLifetimes { generics: self }
72+
}
73+
}
74+
75+
impl<'a> ToTokens for UnderscoreLifetimes<'a> {
76+
fn to_tokens(&self, tokens: &mut TokenStream) {
77+
let Lifetimes {
78+
lt_token,
79+
lifetimes,
80+
gt_token,
81+
} = self.generics;
82+
lt_token.to_tokens(tokens);
83+
for pair in lifetimes.pairs() {
84+
let (lifetime, punct) = pair.into_tuple();
85+
let lifetime = Lifetime::new("'_", lifetime.span());
86+
lifetime.to_tokens(tokens);
87+
punct.to_tokens(tokens);
88+
}
89+
gt_token.to_tokens(tokens);
90+
}
91+
}

0 commit comments

Comments
 (0)