Skip to content

Commit

Permalink
Fixed debug implementations for vtables containing function pointers …
Browse files Browse the repository at this point in the history
…with HRTBs

See rust-lang/rust#70263.
  • Loading branch information
kotauskas committed Apr 13, 2021
1 parent 6fa1bf5 commit f568c8c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
11 changes: 7 additions & 4 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ use thin_trait_object::*;

#[thin_trait_object]
trait Foo {
fn fooify(&self);
fn fooify(&self, extra_data: &str);
}
impl Foo for String {
fn fooify(&self) {
println!("Fooified a string: {}", self);
fn fooify(&self, extra_data: &str) {
println!(
"Fooified a string: \"{}\" with extra data: \"{}\"",
self, extra_data
);
}
}

fn main() {
BoxedFoo::new("Hello World!".to_string()).fooify();
BoxedFoo::new("Hello World!".to_string()).fooify("Another string!");
}
43 changes: 40 additions & 3 deletions src/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use syn::{
FnArg,
GenericParam,
Generics,
LitStr,
Pat,
PatIdent,
PatType,
Expand Down Expand Up @@ -78,7 +79,31 @@ pub fn generate_vtable(
quote! { #name : #ty }
}
}
let items = items.iter().cloned().map(VtableItemToFnPtr);
struct VtableItemToDebugImplLine(VtableItem);
impl<'a> ToTokens for VtableItemToDebugImplLine {
fn to_tokens(&self, out: &mut TokenStream) {
out.extend(self.to_token_stream());
}
fn to_token_stream(&self) -> TokenStream {
let name = self.0.name.clone();
let namelit = LitStr::new(&name.to_string(), Span::call_site());
quote! { .field(#namelit, &(self.#name as *mut ())) }
}
}
struct VtableItemToHashImplLine(VtableItem);
impl<'a> ToTokens for VtableItemToHashImplLine {
fn to_tokens(&self, out: &mut TokenStream) {
out.extend(self.to_token_stream());
}
fn to_token_stream(&self) -> TokenStream {
let name = self.0.name.clone();
quote! { (self.#name as *mut ()).hash(state) }
}
}
let vtable_entries = items.iter().cloned().map(VtableItemToFnPtr);
let debug_impl_lines = items.iter().cloned().map(VtableItemToDebugImplLine);
let hash_impl_lines = items.iter().cloned().map(VtableItemToHashImplLine);
let name_strlit = LitStr::new(&name.to_string(), Span::call_site());
let size_and_align = if store_layout {
quote! {
pub size: usize,
Expand All @@ -88,13 +113,25 @@ pub fn generate_vtable(
quote! {}
};
quote! {
#[derive(Copy, Clone, Debug, Hash)]
#[derive(Copy, Clone)]
#all_attributes
#visibility struct #name {
#size_and_align
#(pub #items,)*
#(pub #vtable_entries,)*
pub drop: unsafe #drop_abi fn(*mut ::core::ffi::c_void),
}
impl ::core::fmt::Debug for #name {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
f.debug_struct(#name_strlit)
#(#debug_impl_lines)*
.finish()
}
}
impl ::core::hash::Hash for #name {
fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
#(#hash_impl_lines;)*
}
}
}
}

Expand Down

0 comments on commit f568c8c

Please sign in to comment.