Improve diagnostics for non-clonable return types

This commit is contained in:
J Henry Waugh 2020-08-27 22:49:56 -05:00
parent 525ffe6f5a
commit 8de095fa36
4 changed files with 74 additions and 4 deletions

View File

@ -314,15 +314,17 @@ impl ExportedFn {
}) })
.collect(); .collect();
let return_span = self.return_type().map(|r| r.span())
.unwrap_or_else(|| proc_macro2::Span::call_site());
if !self.params.return_raw { if !self.params.return_raw {
quote! { quote_spanned! { return_span=>
type EvalBox = Box<EvalAltResult>; type EvalBox = Box<EvalAltResult>;
pub #dynamic_signature { pub #dynamic_signature {
Ok(Dynamic::from(super::#name(#(#arguments),*))) Ok(Dynamic::from(super::#name(#(#arguments),*)))
} }
} }
} else { } else {
quote_spanned! { self.return_type().unwrap().span()=> quote_spanned! { return_span=>
type EvalBox = Box<EvalAltResult>; type EvalBox = Box<EvalAltResult>;
pub #dynamic_signature { pub #dynamic_signature {
super::#name(#(#arguments),*) super::#name(#(#arguments),*)
@ -484,12 +486,14 @@ impl ExportedFn {
// Handle "raw returns", aka cases where the result is a dynamic or an error. // Handle "raw returns", aka cases where the result is a dynamic or an error.
// //
// This allows skipping the Dynamic::from wrap. // This allows skipping the Dynamic::from wrap.
let return_span = self.return_type().map(|r| r.span())
.unwrap_or_else(|| proc_macro2::Span::call_site());
let return_expr = if !self.params.return_raw { let return_expr = if !self.params.return_raw {
quote! { quote_spanned! { return_span=>
Ok(Dynamic::from(#sig_name(#(#unpack_exprs),*))) Ok(Dynamic::from(#sig_name(#(#unpack_exprs),*)))
} }
} else { } else {
quote_spanned! { self.return_type().unwrap().span()=> quote_spanned! { return_span=>
#sig_name(#(#unpack_exprs),*) #sig_name(#(#unpack_exprs),*)
} }
}; };

View File

@ -0,0 +1,27 @@
use rhai::plugin::*;
struct NonClonable {
a: f32,
b: u32,
c: char,
d: bool,
}
#[export_fn]
pub fn test_fn(input: f32) -> NonClonable {
NonClonable {
a: input,
b: 10,
c: 'a',
d: true,
}
}
fn main() {
let n = test_fn(20.0);
if n.c == 'a' {
println!("yes");
} else {
println!("no");
}
}

View File

@ -0,0 +1,10 @@
error[E0277]: the trait bound `NonClonable: std::clone::Clone` is not satisfied
--> $DIR/rhai_fn_non_clonable_return.rs:11:8
|
11 | pub fn test_fn(input: f32) -> NonClonable {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `NonClonable`
|
::: /home/cryptkeeper/Desktop/Software/ytdl-replacement/rhai/src/any.rs:537:30
|
537 | pub fn from<T: Variant + Clone>(value: T) -> Self {
| ----- required by this bound in `rhai::Dynamic::from`

View File

@ -0,0 +1,29 @@
use rhai::plugin::*;
struct NonClonable {
a: f32,
b: u32,
c: char,
d: bool,
}
#[export_module]
pub mod test_mod {
pub fn test_fn(input: f32) -> NonClonable {
NonClonable {
a: input,
b: 10,
c: 'a',
d: true,
}
}
}
fn main() {
let n = test_mod::test_fn(20.0);
if n.c == 'a' {
println!("yes");
} else {
println!("no");
}
}