Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions stabby-macros/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,10 +679,10 @@ impl DynTraitDescription<'_> {
.map(|fn_ptr | {
let DynTraitFn {
ident,
generics: _,
generics,
abi,
unsafety,
receiver: syn::Receiver {mutability, reference: Some((_, lt)), self_token, ..},
receiver: syn::Receiver {mutability, reference: Some((_, receiver_lt)), self_token, ..},
inputs,
output,
} = fn_ptr else {panic!("Only references and mutable references are supported")};
Expand All @@ -697,15 +697,22 @@ impl DynTraitDescription<'_> {
.zip(arg_tys.iter())
.map(|(name, ty)| quote!(#name: #ty))
.collect::<Vec<_>>();
let mut arg_lts = generics.lifetimes().cloned().collect::<Vec<_>>();
let output = output.as_ref().map(|ty| {
let ty = self.self_dependent_types.unselfed(ty);
quote!(-> #ty)
});
let lt = lt.clone().unwrap_or_else(|| Lifetime::new("'stabby_receiver_lt", self_token.span()));
let receiver_lt = if let Some(lt) = receiver_lt {
lt.clone()
} else {
let default_lt = Lifetime::new("'stabby_receiver_lt", self_token.span());
arg_lts.push(syn::LifetimeDef::new(default_lt.clone()));
default_lt
};
let receiver = if mutability.is_some() {
quote!(#st::AnonymRefMut<#lt>)
quote!(#st::AnonymRefMut<#receiver_lt>)
} else {
quote!(#st::AnonymRef<#lt>)
quote!(#st::AnonymRef<#receiver_lt>)
};
let as_ref = if mutability.is_some() {
quote!(as_mut())
Expand All @@ -715,13 +722,13 @@ impl DynTraitDescription<'_> {
let mut ctor = quote!(#st::StableLike::new({
#unsafety #abi fn #ext_ident <
'stabby_local_lt,
#lt,
#(#trait_lts,)*
#(#arg_lts,)*
StabbyArbitraryType: 'stabby_local_lt,
#(#dyntrait_types,)*
#(#trait_types,)*
#(#trait_consts,)*
>(this: #receiver, _lt_proof: ::core::marker::PhantomData<&#lt &'stabby_local_lt ()>, #(#args,)*) #output
>(this: #receiver, _lt_proof: ::core::marker::PhantomData<&#receiver_lt &'stabby_local_lt ()>, #(#args,)*) #output
where
StabbyArbitraryType: #trait_id <#(#unbound_trait_lts,)* #(#unbound_trait_types,)* #(#unbound_trait_consts,)* #(#trait_to_vt_bindings,)* >,
#(#vt_bounds)*
Expand All @@ -735,9 +742,9 @@ impl DynTraitDescription<'_> {
}
}
#ext_ident :: < StabbyArbitraryType, #(#dyntrait_types,)* #(#unbound_trait_types,)* #(#unbound_trait_consts,)* > as for <
#lt,
#(#trait_lts,)*
> #unsafety #abi fn (#receiver, ::core::marker::PhantomData<&#lt &'stabby_vt_lt ()>, #(#arg_tys,)*) #output
#(#arg_lts,)*
> #unsafety #abi fn (#receiver, ::core::marker::PhantomData<&#receiver_lt &'stabby_vt_lt ()>, #(#arg_tys,)*) #output
}));
if self.check_bounds {
ctor = quote!(#st::StableIf::new(#ctor))
Expand Down
9 changes: 9 additions & 0 deletions stabby/src/tests/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub trait MyTrait {
type Output;
extern "C" fn do_stuff<'a>(&'a self, with: &'a Self::Output) -> &'a u8;
extern "C" fn gen_stuff(&mut self) -> Self::Output;
extern "C" fn filter_stuff<'a>(&self, source: &'a u8) -> &'a u8;
}

// IMPL
Expand All @@ -36,6 +37,9 @@ impl MyTrait for u8 {
extern "C" fn gen_stuff(&mut self) -> Self::Output {
*self
}
extern "C" fn filter_stuff<'a>(&self, source: &'a u8) -> &'a u8 {
source
}
}
impl MyTrait for u16 {
type Output = u8;
Expand All @@ -45,6 +49,9 @@ impl MyTrait for u16 {
extern "C" fn gen_stuff(&mut self) -> Self::Output {
*self as u8
}
extern "C" fn filter_stuff<'a>(&self, source: &'a u8) -> &'a u8 {
source
}
}

// MYTRAIT2
Expand Down Expand Up @@ -141,6 +148,8 @@ fn dyn_traits() {
)>::from(boxed);
assert_eq!(dyned.do_stuff(&0), &6);
assert_eq!(dyned.gen_stuff(), 6);
let value = 33u8;
assert_eq!(&value as *const _, dyned.filter_stuff(&value) as *const _);
assert_eq!(dyned.gen_stuff3(Box::new(())), 6);
// assert_eq!(unsafe { dyned.downcast_ref::<u8>() }, Some(&6));
// assert!(unsafe { dyned.downcast_ref::<u16>() }.is_none());
Expand Down
Loading