rust/tests/run-pass-valgrind/unsized-locals/by-value-trait-objects-rust-call2.rs
2024-06-04 09:53:02 +10:00

70 lines
2.2 KiB
Rust

#![feature(unsized_locals)]
#![feature(unboxed_closures)]
#![feature(tuple_trait)]
pub trait FnOnce<Args: std::marker::Tuple> {
type Output;
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}
struct A;
impl FnOnce<(String, Box<str>)> for A {
type Output = String;
extern "rust-call" fn call_once(self, (s1, s2): (String, Box<str>)) -> Self::Output {
assert_eq!(&s1 as &str, "s1");
assert_eq!(&s2 as &str, "s2");
format!("hello")
}
}
struct B(i32);
impl FnOnce<(String, Box<str>)> for B {
type Output = String;
extern "rust-call" fn call_once(self, (s1, s2): (String, Box<str>)) -> Self::Output {
assert_eq!(&s1 as &str, "s1");
assert_eq!(&s2 as &str, "s2");
format!("{}", self.0)
}
}
struct C(String);
impl FnOnce<(String, Box<str>)> for C {
type Output = String;
extern "rust-call" fn call_once(self, (s1, s2): (String, Box<str>)) -> Self::Output {
assert_eq!(&s1 as &str, "s1");
assert_eq!(&s2 as &str, "s2");
self.0
}
}
struct D(Box<String>);
impl FnOnce<(String, Box<str>)> for D {
type Output = String;
extern "rust-call" fn call_once(self, (s1, s2): (String, Box<str>)) -> Self::Output {
assert_eq!(&s1 as &str, "s1");
assert_eq!(&s2 as &str, "s2");
*self.0
}
}
fn main() {
let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str());
let x = *(Box::new(A) as Box<dyn FnOnce<(String, Box<str>), Output = String>>);
assert_eq!(x.call_once((s1, s2)), format!("hello"));
let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str());
let x = *(Box::new(B(42)) as Box<dyn FnOnce<(String, Box<str>), Output = String>>);
assert_eq!(x.call_once((s1, s2)), format!("42"));
let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str());
let x = *(Box::new(C(format!("jumping fox")))
as Box<dyn FnOnce<(String, Box<str>), Output = String>>);
assert_eq!(x.call_once((s1, s2)), format!("jumping fox"));
let (s1, s2) = (format!("s1"), format!("s2").into_boxed_str());
let x = *(Box::new(D(Box::new(format!("lazy dog"))))
as Box<dyn FnOnce<(String, Box<str>), Output = String>>);
assert_eq!(x.call_once((s1, s2)), format!("lazy dog"));
}