Skip to content

Commit

Permalink
Fallback to debug-printing generic info (#682)
Browse files Browse the repository at this point in the history
Co-authored-by: John-John Tedro <[email protected]>
  • Loading branch information
tgolsson and udoprog authored Mar 30, 2024
1 parent fc2bc0c commit fea782a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 6 deletions.
6 changes: 6 additions & 0 deletions crates/rune/src/runtime/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ impl<T: ?Sized> Shared<T> {
}
}

impl<T: ?Sized> fmt::Pointer for Shared<T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Pointer::fmt(&self.inner.as_ptr(), fmt)
}
}

impl<T: ?Sized> TryClone for Shared<T> {
#[inline]
fn try_clone(&self) -> alloc::Result<Self> {
Expand Down
11 changes: 8 additions & 3 deletions crates/rune/src/runtime/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -851,11 +851,16 @@ impl Value {
vm_write!(f, "{:?}", value);
}
_ => {
// reborrow f to avoid moving it
let result =
vm_try!(caller.call_protocol_fn(Protocol::STRING_DEBUG, self.clone(), (f,)));
caller.call_protocol_fn(Protocol::STRING_DEBUG, self.clone(), (&mut *f,));

vm_try!(<()>::from_value(result));
return VmResult::Ok(());
if let VmResult::Ok(result) = result {
vm_try!(<()>::from_value(result));
} else {
let type_info = vm_try!(self.type_info());
vm_write!(f, "<{} object at {:p}>", type_info, self.inner);
}
}
};

Expand Down
8 changes: 5 additions & 3 deletions crates/rune/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
pub(crate) mod prelude {
pub(crate) use crate as rune;
pub(crate) use crate::alloc;
pub(crate) use crate::alloc::fmt::TryWrite;
pub(crate) use crate::alloc::prelude::*;
pub(crate) use crate::ast;
pub(crate) use crate::compile::{self, ErrorKind, Item, ItemBuf, Located, Named};
Expand All @@ -14,9 +15,9 @@ pub(crate) mod prelude {
pub(crate) use crate::module::InstallWith;
pub(crate) use crate::parse;
pub(crate) use crate::runtime::{
self, AnyTypeInfo, Bytes, FullTypeOf, Function, MaybeTypeOf, Mut, Object, OwnedTuple,
Protocol, RawRef, RawStr, Ref, Stack, Tuple, TypeInfo, TypeOf, UnsafeToRef, ValueKind,
VecTuple, VmErrorKind, VmResult,
self, AnyTypeInfo, Bytes, Formatter, FullTypeOf, Function, MaybeTypeOf, Mut, Object,
OwnedTuple, Protocol, RawRef, RawStr, Ref, Stack, Tuple, TypeInfo, TypeOf, UnsafeToRef,
ValueKind, VecTuple, VmErrorKind, VmResult,
};
pub(crate) use crate::support::Result;
pub(crate) use crate::tests::run;
Expand Down Expand Up @@ -450,6 +451,7 @@ mod reference_error;
mod rename_type;
mod result;
mod stmt_reordering;
mod string_debug;
mod tuple;
mod type_name_native;
mod type_name_rune;
Expand Down
60 changes: 60 additions & 0 deletions crates/rune/src/tests/string_debug.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//! Tests for `std::any::type_name_of_val(v)` for native types
prelude!();

#[derive(Any, Debug)]
#[rune(item = ::native_crate)]
pub struct NativeStructWithProtocol;

impl NativeStructWithProtocol {
#[rune::function(protocol = STRING_DEBUG)]
fn string_debug(&self, f: &mut Formatter) -> VmResult<()> {
vm_write!(f, "{:?}", self);

VmResult::Ok(())
}
}

#[derive(Any)]
#[rune(item = ::native_crate)]
pub struct NativeStructWithoutProtocol;

fn make_native_module() -> Result<Module, ContextError> {
let mut module = Module::with_crate("native_crate")?;
module.ty::<NativeStructWithProtocol>()?;
module.function_meta(NativeStructWithProtocol::string_debug)?;
module.ty::<NativeStructWithoutProtocol>()?;

Ok(module)
}

#[test]
fn test_with_string_debug() {
let t1 = NativeStructWithProtocol;
assert_eq!(
rune_n! {
make_native_module().expect("failed making native module"),
(t1, ),
String =>
pub fn main(v) { format!("{:?}", v) }
},
"NativeStructWithProtocol"
);
}

#[test]
fn test_without_string_debug() {
let t1 = NativeStructWithoutProtocol;
let result = rune_n! {
make_native_module().expect("failed making native module"),
(t1, ),
String =>
pub fn main(v) { format!("{:?}", v) }
};

assert!(
result.starts_with("<NativeStructWithoutProtocol object at 0x"),
"Expected '<NativeStructWithoutProtocol object at 0x', got: {:?}",
result
);
}

0 comments on commit fea782a

Please sign in to comment.