Skip to content

Commit

Permalink
Fixed impl Debug for function pointers with HRTBs
Browse files Browse the repository at this point in the history
Function pointers don't implement Debug if some of their arguments are
references, as seen in rust-lang/rust#70263.
  • Loading branch information
kotauskas committed Apr 13, 2021
1 parent 6fa1bf5 commit df2ae13
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 df2ae13

Please sign in to comment.