diff --git a/crates/rune/src/compile/options.rs b/crates/rune/src/compile/options.rs index a30415d65..cf9b0ba32 100644 --- a/crates/rune/src/compile/options.rs +++ b/crates/rune/src/compile/options.rs @@ -128,7 +128,7 @@ pub struct Options { impl Options { /// The default options. - const DEFAULT: Options = Options { + pub(crate) const DEFAULT: Options = Options { link_checks: true, memoize_instance_fn: true, debug_info: true, @@ -442,4 +442,17 @@ impl Options { pub fn memoize_instance_fn(&mut self, enabled: bool) { self.memoize_instance_fn = enabled; } + + /// Whether to build sources as scripts where the source is executed like a + /// function body. + pub fn script(&mut self, enabled: bool) { + self.function_body = enabled; + } +} + +impl Default for Options { + #[inline] + fn default() -> Self { + Options::DEFAULT + } } diff --git a/crates/rune/src/modules/collections/hash_map.rs b/crates/rune/src/modules/collections/hash_map.rs index 969923d41..bc051c50b 100644 --- a/crates/rune/src/modules/collections/hash_map.rs +++ b/crates/rune/src/modules/collections/hash_map.rs @@ -61,6 +61,78 @@ pub fn module() -> Result { Ok(m) } +/// A [hash map] implemented with quadratic probing and SIMD lookup. +/// +/// By default, `HashMap` uses a hashing algorithm selected to provide +/// resistance against HashDoS attacks. The algorithm is randomly seeded, and a +/// reasonable best-effort is made to generate this seed from a high quality, +/// secure source of randomness provided by the host without blocking the +/// program. Because of this, the randomness of the seed depends on the output +/// quality of the system's random number coroutine when the seed is created. In +/// particular, seeds generated when the system's entropy pool is abnormally low +/// such as during system boot may be of a lower quality. +/// +/// The default hashing algorithm is currently SipHash 1-3, though this is +/// subject to change at any point in the future. While its performance is very +/// competitive for medium sized keys, other hashing algorithms will outperform +/// it for small keys such as integers as well as large keys such as long +/// strings, though those algorithms will typically *not* protect against +/// attacks such as HashDoS. +/// +/// The hashing algorithm can be replaced on a per-`HashMap` basis using the +/// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. +/// There are many alternative [hashing algorithms available on crates.io]. +/// +/// It is required that the keys implement the [`EQ`] and [`HASH`] protocols. If +/// you implement these yourself, it is important that the following property +/// holds: +/// +/// ```text +/// k1 == k2 -> hash(k1) == hash(k2) +/// ``` +/// +/// In other words, if two keys are equal, their hashes must be equal. Violating +/// this property is a logic error. +/// +/// It is also a logic error for a key to be modified in such a way that the +/// key's hash, as determined by the [`HASH`] protocol, or its equality, as +/// determined by the [`EQ`] protocol, changes while it is in the map. This is +/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or +/// unsafe code. +/// +/// The behavior resulting from either logic error is not specified, but will be +/// encapsulated to the `HashMap` that observed the logic error and not result +/// in undefined behavior. This could include panics, incorrect results, aborts, +/// memory leaks, and non-termination. +/// +/// The hash table implementation is a Rust port of Google's [SwissTable]. The +/// original C++ version of SwissTable can be found [here], and this [CppCon +/// talk] gives an overview of how the algorithm works. +/// +/// [hash map]: crate::collections#use-a-hashmap-when +/// [hashing algorithms available on crates.io]: https://crates.io/keywords/hasher +/// [SwissTable]: https://abseil.io/blog/20180927-swisstables +/// [here]: https://github.com/abseil/abseil-cpp/blob/master/absl/container/internal/raw_hash_set.h +/// [CppCon talk]: https://www.youtube.com/watch?v=ncHmEUmJZf4 +/// +/// # Examples +/// +/// ```rune +/// use std::collections::HashMap; +/// +/// enum Tile { +/// Wall, +/// } +/// +/// let m = HashMap::new(); +/// +/// m.insert((0, 1), Tile::Wall); +/// m[(0, 3)] = 5; +/// +/// assert_eq!(m.get((0, 1)), Some(Tile::Wall)); +/// assert_eq!(m.get((0, 2)), None); +/// assert_eq!(m[(0, 3)], 5); +/// ``` #[derive(Any)] #[rune(item = ::std::collections::hash_map)] pub(crate) struct HashMap { diff --git a/crates/rune/src/modules/collections/hash_set.rs b/crates/rune/src/modules/collections/hash_set.rs index 1d8ee04b3..816d84079 100644 --- a/crates/rune/src/modules/collections/hash_set.rs +++ b/crates/rune/src/modules/collections/hash_set.rs @@ -66,6 +66,49 @@ pub fn module() -> Result { Ok(m) } +/// A [hash set] implemented as a `HashMap` where the value is `()`. +/// +/// As with the [`HashMap`] type, a `HashSet` requires that the elements +/// implement the [`EQ`] and [`HASH`] protocols. If you implement these +/// yourself, it is important that the following property holds: +/// +/// ```text +/// k1 == k2 -> hash(k1) == hash(k2) +/// ``` +/// +/// In other words, if two keys are equal, their hashes must be equal. Violating +/// this property is a logic error. +/// +/// It is also a logic error for a key to be modified in such a way that the +/// key's hash, as determined by the [`HASH`] protocol, or its equality, as +/// determined by the [`EQ`] protocol, changes while it is in the map. This is +/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or +/// unsafe code. +/// +/// The behavior resulting from either logic error is not specified, but will be +/// encapsulated to the `HashSet` that observed the logic error and not result +/// in undefined behavior. This could include panics, incorrect results, aborts, +/// memory leaks, and non-termination. +/// +/// [hash set]: crate::collections#use-the-set-variant-of-any-of-these-maps-when +/// [`HashMap`]: crate::collections::HashMap +/// +/// # Examples +/// +/// ```rune +/// use std::collections::HashSet; +/// +/// enum Tile { +/// Wall, +/// } +/// +/// let m = HashSet::new(); +/// +/// m.insert((0, 1)); +/// +/// assert!(m.contains((0, 1))); +/// assert!(!m.contains((0, 2))); +/// ``` #[derive(Any)] #[rune(module = crate, item = ::std::collections::hash_set)] pub(crate) struct HashSet { diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index cd8f8ac21..07c3ba61f 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -381,11 +381,11 @@ impl Vm { /// println!("output: {}", output); /// # Ok::<_, rune::support::Error>(()) /// ``` - pub fn execute(&mut self, name: N, args: A) -> Result, VmError> - where - N: ToTypeHash, - A: Args, - { + pub fn execute( + &mut self, + name: impl ToTypeHash, + args: impl Args, + ) -> Result, VmError> { self.set_entrypoint(name, args.count())?; args.into_stack(&mut self.stack).into_result()?; Ok(VmExecution::new(self)) @@ -397,11 +397,11 @@ impl Vm { /// This is accomplished by preventing values escaping from being /// non-exclusively sent with the execution or escaping the execution. We /// only support encoding arguments which themselves are `Send`. - pub fn send_execute(mut self, name: N, args: A) -> Result - where - N: ToTypeHash, - A: Send + Args, - { + pub fn send_execute( + mut self, + name: impl ToTypeHash, + args: impl Args + Send, + ) -> Result { // Safety: make sure the stack is clear, preventing any values from // being sent along with the virtual machine. self.stack.clear(); diff --git a/crates/rune/src/tests.rs b/crates/rune/src/tests.rs index f05b7749f..792b27d5c 100644 --- a/crates/rune/src/tests.rs +++ b/crates/rune/src/tests.rs @@ -25,7 +25,7 @@ pub(crate) mod prelude { pub(crate) use crate::tests::{eval, run}; pub(crate) use crate::{ from_value, prepare, sources, span, vm_try, Any, Context, ContextError, Diagnostics, - FromValue, Hash, Item, ItemBuf, Module, Source, Sources, Value, Vm, + FromValue, Hash, Item, ItemBuf, Module, Options, Source, Sources, Value, Vm, }; pub(crate) use futures_executor::block_on; @@ -43,11 +43,10 @@ use ::rust_alloc::sync::Arc; use anyhow::{Context as _, Error, Result}; -use crate::alloc; -use crate::item::IntoComponent; use crate::runtime::{Args, VmError}; use crate::{ - termcolor, BuildError, Context, Diagnostics, FromValue, ItemBuf, Source, Sources, Unit, Vm, + alloc, termcolor, BuildError, Context, Diagnostics, FromValue, Hash, Options, Source, Sources, + Unit, Vm, }; /// An error that can be raised during testing. @@ -97,9 +96,13 @@ pub fn compile_helper(source: &str, diagnostics: &mut Diagnostics) -> Result Result { + let mut options = Options::default(); + + if script { + options.script(true); + } + let result = crate::prepare(sources) .with_context(context) .with_diagnostics(diagnostics) + .with_options(&options) .build(); let Ok(unit) = result else { @@ -134,24 +145,23 @@ pub fn vm( /// Call the specified function in the given script sources. #[doc(hidden)] -pub fn run_helper( +pub fn run_helper( context: &Context, sources: &mut Sources, diagnostics: &mut Diagnostics, - function: N, - args: A, + args: impl Args, + script: bool, ) -> Result where - N: IntoIterator, - N::Item: IntoComponent, - A: Args, T: FromValue, { - let mut vm = vm(context, sources, diagnostics)?; + let mut vm = vm(context, sources, diagnostics, script)?; - let item = ItemBuf::with_item(function)?; - - let mut execute = vm.execute(&item, args).map_err(TestError::VmError)?; + let mut execute = if script { + vm.execute(Hash::EMPTY, args).map_err(TestError::VmError)? + } else { + vm.execute(["main"], args).map_err(TestError::VmError)? + }; let output = ::futures_executor::block_on(execute.async_complete()) .into_result() @@ -170,19 +180,16 @@ pub fn sources(source: &str) -> Sources { } /// Run the given source with diagnostics being printed to stderr. -pub fn run(context: &Context, source: &str, function: N, args: A) -> Result +pub fn run(context: &Context, source: &str, args: impl Args, script: bool) -> Result where - N: IntoIterator, - N::Item: IntoComponent, - A: Args, T: FromValue, { let mut sources = Sources::new(); - sources.insert(Source::new("main", source)?)?; + sources.insert(Source::memory(source)?)?; let mut diagnostics = Default::default(); - let e = match run_helper(context, &mut sources, &mut diagnostics, function, args) { + let e = match run_helper(context, &mut sources, &mut diagnostics, args, script) { Ok(value) => return Ok(value), Err(e) => e, }; @@ -229,7 +236,7 @@ where let source = source.as_ref(); let context = Context::with_default_modules().expect("Failed to build context"); - match run(&context, source, ["main"], ()) { + match run(&context, source, (), true) { Ok(output) => output, Err(error) => { panic!("Program failed to run:\n{error}\n{source}"); @@ -257,10 +264,10 @@ macro_rules! rune_assert { /// of native Rust data. This also accepts a tuple of arguments in the second /// position, to pass native objects as arguments to the script. macro_rules! rune_n { - ($module:expr, $args:expr, $ty:ty => $($tt:tt)*) => {{ + ($(mod $module:expr,)* $args:expr, $($tt:tt)*) => {{ let mut context = $crate::Context::with_default_modules().expect("Failed to build context"); - context.install($module).expect("Failed to install native module"); - $crate::tests::run::<_, _, $ty>(&context, stringify!($($tt)*), ["main"], $args).expect("Program ran unsuccessfully") + $(context.install(&$module).expect("Failed to install native module");)* + $crate::tests::run(&context, stringify!($($tt)*), $args, false).expect("Program ran unsuccessfully") }}; } @@ -277,7 +284,7 @@ macro_rules! assert_vm_error { let mut diagnostics = Default::default(); let mut sources = $crate::tests::sources($source); - let e = match $crate::tests::run_helper::<_, _, $ty>(&context, &mut sources, &mut diagnostics, ["main"], ()) { + let e = match $crate::tests::run_helper::<$ty>(&context, &mut sources, &mut diagnostics, (), true) { Err(e) => e, actual => { expected!("program error", Err(e), actual, $source) @@ -430,8 +437,6 @@ mod builtin_macros; #[cfg(not(miri))] mod capture; #[cfg(not(miri))] -mod collections; -#[cfg(not(miri))] mod comments; #[cfg(not(miri))] mod compiler_docs; diff --git a/crates/rune/src/tests/attribute.rs b/crates/rune/src/tests/attribute.rs index 5dc94c316..2b8e6c819 100644 --- a/crates/rune/src/tests/attribute.rs +++ b/crates/rune/src/tests/attribute.rs @@ -16,9 +16,6 @@ fn basic_use() { fn test_case() { assert_eq!(1 + 1, 2); } - - pub fn main() { - } }; } @@ -144,8 +141,8 @@ fn deny_mod_attributes() { #[test] fn deny_local_attributes() { assert_errors! { - "pub fn main() { #[local_attribute] let x = 1; }", - span!(16, 34), Custom { error } => { + "#[local_attribute] let x = 1;", + span!(0, 18), Custom { error } => { assert_eq!(error.to_string(), "Attributes on local declarations are not supported"); } }; @@ -154,8 +151,8 @@ fn deny_local_attributes() { #[test] fn deny_block_attributes() { assert_errors! { - r#"pub fn main() { #[block_attribute] {} }"#, - span!(16, 34), Custom { error } => { + "#[block_attribute] {}", + span!(0, 18), Custom { error } => { assert_eq!(error.to_string(), "Attributes on blocks are not supported"); } }; @@ -164,9 +161,16 @@ fn deny_block_attributes() { #[test] fn deny_macro_attributes() { assert_errors! { - r#"#[macro_attribute] macro_call!()"#, + "#[macro_attribute] macro_call!()", span!(0, 18), Custom { error } => { - assert_eq!(error.to_string(), "Attributes on macros are not supported"); + assert_eq!(error.to_string(), "Unsupported macro attribute"); + } + }; + + assert_errors! { + "fn inner() { #[macro_attribute] macro_call!() }", + span!(13, 31), Custom { error } => { + assert_eq!(error.to_string(), "Unsupported macro attribute"); } }; } @@ -174,7 +178,7 @@ fn deny_macro_attributes() { #[test] fn deny_field_attributes() { assert_errors! { - r#"struct Struct { #[field_attribute] field }"#, + "struct Struct { #[field_attribute] field }", span!(16, 34), Custom { error } => { assert_eq!(error.to_string(), "Attributes on fields are not supported"); } @@ -184,7 +188,7 @@ fn deny_field_attributes() { #[test] fn deny_variant_attributes() { assert_errors! { - r#"enum Enum { #[field_attribute] Variant }"#, + "enum Enum { #[field_attribute] Variant }", span!(12, 30), Custom { error } => { assert_eq!(error.to_string(), "Attributes on variants are not supported"); } @@ -194,7 +198,7 @@ fn deny_variant_attributes() { #[test] fn deny_variant_field_attributes() { assert_errors! { - r#"enum Enum { Variant { #[field_attribute] field } }"#, + "enum Enum { Variant { #[field_attribute] field } }", span!(22, 40), Custom { error } => { assert_eq!(error.to_string(), "Attributes on variant fields are not supported"); } @@ -204,8 +208,8 @@ fn deny_variant_field_attributes() { #[test] fn deny_expr_attributes() { assert_errors! { - r#"pub fn main() { #[expr_attribute] 42 }"#, - span!(16, 33), Custom { error } => { + "#[expr_attribute] 42", + span!(0, 17), Custom { error } => { assert_eq!(error.to_string(), "Attributes on expressions are not supported"); } }; diff --git a/crates/rune/src/tests/binary.rs b/crates/rune/src/tests/binary.rs index d23695820..31a58a759 100644 --- a/crates/rune/src/tests/binary.rs +++ b/crates/rune/src/tests/binary.rs @@ -5,35 +5,24 @@ use ErrorKind::*; #[test] fn test_binary_exprs() { assert_errors! { - r#"pub fn main() { 0 < 10 >= 10 }"#, - span, PrecedenceGroupRequired => { - assert_eq!(span, span!(16, 22)); + r#"0 < 10 >= 10"#, + span!(0, 6), PrecedenceGroupRequired => { } }; // Test solving precedence with groups. - assert_parse!(r#"pub fn main() { (0 < 10) >= 10 }"#); - assert_parse!(r#"pub fn main() { 0 < (10 >= 10) }"#); - assert_parse!(r#"pub fn main() { 0 < 10 && 10 > 0 }"#); - assert_parse!(r#"pub fn main() { 0 < 10 && 10 > 0 || true }"#); - assert_parse!(r#"pub fn main() { false || return }"#); + assert_parse!(r#"(0 < 10) >= 10"#); + assert_parse!(r#"0 < (10 >= 10)"#); + assert_parse!(r#"0 < 10 && 10 > 0"#); + assert_parse!(r#"0 < 10 && 10 > 0 || true"#); + assert_parse!(r#"false || return"#); } #[test] fn test_basic_operator_precedence() { - let result: bool = rune! { - pub fn main() { - 10 < 5 + 10 && 5 > 4 - } - }; - + let result: bool = rune!(10 < 5 + 10 && 5 > 4); assert!(result); - let result: bool = rune! { - pub fn main() { - 10 < 5 - 10 && 5 > 4 - } - }; - + let result: bool = rune!(10 < 5 - 10 && 5 > 4); assert!(!result); } diff --git a/crates/rune/src/tests/bug_422.rs b/crates/rune/src/tests/bug_422.rs index 0481df71b..635e1d592 100644 --- a/crates/rune/src/tests/bug_422.rs +++ b/crates/rune/src/tests/bug_422.rs @@ -8,10 +8,7 @@ prelude!(); pub fn test_bug_422() { macro_rules! test_case { ($expr:expr) => { - let value: u32 = rune! { - pub fn main() { $expr } - }; - + let value: u32 = rune!($expr); assert_eq!(value, $expr); }; } diff --git a/crates/rune/src/tests/bug_428.rs b/crates/rune/src/tests/bug_428.rs index 24c7c6568..2dc40c776 100644 --- a/crates/rune/src/tests/bug_428.rs +++ b/crates/rune/src/tests/bug_428.rs @@ -3,11 +3,9 @@ prelude!(); #[test] pub fn test_bug_428() { let (a, b): (String, String) = rune! { - pub fn main() { - let a = format!("{:>} = {:>}", "AB", 0x1234); - let b = format!("{:>} = {:08}", "AB", 0x1234); - (a, b) - } + let a = format!("{:>} = {:>}", "AB", 0x1234); + let b = format!("{:>} = {:08}", "AB", 0x1234); + (a, b) }; assert_eq!(a, "AB = 4660"); diff --git a/crates/rune/src/tests/bug_454.rs b/crates/rune/src/tests/bug_454.rs index cf210ae7e..d625ab515 100644 --- a/crates/rune/src/tests/bug_454.rs +++ b/crates/rune/src/tests/bug_454.rs @@ -16,9 +16,7 @@ pub fn test_bug_454() { } } - pub fn main() { - let test = Test; - assert_eq!(test.call(), 3); - } + let test = Test; + assert_eq!(test.call(), 3); }; } diff --git a/crates/rune/src/tests/bugfixes.rs b/crates/rune/src/tests/bugfixes.rs index 2cb3f314b..87ea01926 100644 --- a/crates/rune/src/tests/bugfixes.rs +++ b/crates/rune/src/tests/bugfixes.rs @@ -16,9 +16,7 @@ fn test_pattern_binding_bug() { x } - pub fn main() { - foo(3) - } + foo(3) }; assert_eq!(out, 3 * 11); @@ -44,9 +42,7 @@ fn test_string_pattern_in_instance_fn_bug() { assert_eq!(program, [Inst::A]); } - pub fn main() { - works(); - broken(); - } + works(); + broken(); }; } diff --git a/crates/rune/src/tests/builtin_macros.rs b/crates/rune/src/tests/builtin_macros.rs index a408b7b6f..4dc3b3ccf 100644 --- a/crates/rune/src/tests/builtin_macros.rs +++ b/crates/rune/src/tests/builtin_macros.rs @@ -12,14 +12,21 @@ macro_rules! capture { let mut context = Context::with_config(false).context("building context")?; context.install(module).context("installing module")?; - let source = Source::memory(concat!("pub fn main() { ", stringify!($($tt)*), " }")).context("building source")?; + let source = Source::memory(stringify!($($tt)*)).context("building source")?; let mut sources = Sources::new(); sources.insert(source).context("inserting source")?; let mut diagnostics = Diagnostics::new(); - let unit = prepare(&mut sources).with_context(&context).with_diagnostics(&mut diagnostics).build(); + let mut options = Options::default(); + options.script(true); + + let unit = prepare(&mut sources) + .with_context(&context) + .with_diagnostics(&mut diagnostics) + .with_options(&options) + .build(); if !diagnostics.is_empty() { let mut writer = StandardStream::stderr(ColorChoice::Always); @@ -32,7 +39,7 @@ macro_rules! capture { let context = Arc::new(context); let mut vm = Vm::new(context, unit); - vm.call(["main"], ()).context("calling main")?; + vm.call(Hash::EMPTY, ()).context("calling main")?; capture.drain_utf8().context("draining utf-8 capture")? }}; } @@ -45,7 +52,7 @@ macro_rules! test_case { let string = capture!($($prefix)* print!($($format)*)); assert_eq!(string, $expected, "Expecting print!"); - let string: String = rune!(pub fn main() { $($prefix)* format!($($format)*) }); + let string: String = rune!($($prefix)* format!($($format)*)); assert_eq!(string, $expected, "Expecting format!"); }} } diff --git a/crates/rune/src/tests/capture.rs b/crates/rune/src/tests/capture.rs index 5d74c0c9e..deaab0e47 100644 --- a/crates/rune/src/tests/capture.rs +++ b/crates/rune/src/tests/capture.rs @@ -3,12 +3,10 @@ prelude!(); #[test] fn test_closure() { let number: i64 = rune! { - pub async fn main() { - let a = 1; - let b = 2; - let closure = { let c = 4; |d, e| |f| a + b + c + d + e + f }; - closure(8, 16)(32) - } + let a = 1; + let b = 2; + let closure = { let c = 4; |d, e| |f| a + b + c + d + e + f }; + closure(8, 16)(32) }; assert_eq!(number, 1 + 2 + 4 + 8 + 16 + 32); @@ -17,12 +15,10 @@ fn test_closure() { #[test] fn test_async() { let number: i64 = rune! { - pub async fn main() { - let a = 1; - let b = 2; - let closure = async { let c = 4; |d, e| |f| a + b + c + d + e + f }; - closure.await(8, 16)(32) - } + let a = 1; + let b = 2; + let closure = async { let c = 4; |d, e| |f| a + b + c + d + e + f }; + closure.await(8, 16)(32) }; assert_eq!(number, 1 + 2 + 4 + 8 + 16 + 32); diff --git a/crates/rune/src/tests/collections.rs b/crates/rune/src/tests/collections.rs deleted file mode 100644 index 897034a38..000000000 --- a/crates/rune/src/tests/collections.rs +++ /dev/null @@ -1,43 +0,0 @@ -prelude!(); - -#[test] -fn test_hash_map_tile() { - let _: () = rune! { - pub fn main() { - use std::collections::HashMap; - - enum Tile { - Wall, - } - - let m = HashMap::new(); - - m.insert((0, 1), Tile::Wall); - m[(0, 3)] = 5; - - assert_eq!(m.get((0, 1)), Some(Tile::Wall)); - assert_eq!(m.get((0, 2)), None); - assert_eq!(m[(0, 3)], 5); - } - }; -} - -#[test] -fn test_hash_set_tuple() { - let _: () = rune! { - pub fn main() { - use std::collections::HashSet; - - enum Tile { - Wall, - } - - let m = HashSet::new(); - - m.insert((0, 1)); - - assert!(m.contains((0, 1))); - assert!(!m.contains((0, 2))); - } - }; -} diff --git a/crates/rune/src/tests/compiler_expr_assign.rs b/crates/rune/src/tests/compiler_expr_assign.rs index 76158be7a..1cb4b5532 100644 --- a/crates/rune/src/tests/compiler_expr_assign.rs +++ b/crates/rune/src/tests/compiler_expr_assign.rs @@ -4,18 +4,18 @@ use ErrorKind::*; #[test] fn assign_expr() { - assert_parse!(r#"pub fn main() { let var = 1; var = 42; }"#); + assert_parse!(r#"let var = 1; var = 42;"#); assert_errors! { - r#"pub fn main() { 1 = 42; }"#, - span!(16, 22), UnsupportedAssignExpr + r#"1 = 42;"#, + span!(0, 6), UnsupportedAssignExpr }; } #[test] fn mut_let() { assert_errors! { - r#"pub fn main() { let mut var = 1; }"#, - span!(20, 23), UnsupportedMut + r#"let mut var = 1;"#, + span!(4, 7), UnsupportedMut }; } diff --git a/crates/rune/src/tests/compiler_general.rs b/crates/rune/src/tests/compiler_general.rs index a8f85e1ae..ed8ee71d0 100644 --- a/crates/rune/src/tests/compiler_general.rs +++ b/crates/rune/src/tests/compiler_general.rs @@ -5,8 +5,8 @@ use ErrorKind::*; #[test] fn test_use_variant_as_type() { assert_errors! { - r#"pub fn main() { Err(0) is Err }"#, - span!(26, 29), ExpectedMeta { meta, .. } => { + "Err(0) is Err", + span!(10, 13), ExpectedMeta { meta, .. } => { assert_eq!(meta.to_string(), "variant ::std::result::Result::Err"); } }; @@ -15,72 +15,72 @@ fn test_use_variant_as_type() { #[test] fn break_outside_of_loop() { assert_errors! { - r#"pub fn main() { break; }"#, - span!(16, 21), BreakUnsupported + "break;", + span!(0, 5), BreakUnsupported }; } #[test] fn for_break_with_value() { assert_errors! { - r#"pub fn main() { for _ in 0..10 { break 42; } }"#, - span!(33, 41), BreakUnsupportedValue + "for _ in 0..10 { break 42; }", + span!(17, 25), BreakUnsupportedValue }; } #[test] fn continue_outside_of_loop() { assert_errors! { - r#"pub fn main() { continue; }"#, - span!(16, 24), ContinueUnsupported + "continue;", + span!(0, 8), ContinueUnsupported }; } #[test] fn test_pointers() { assert_errors! { - r#"pub fn main() { let n = 0; foo(&n); } fn foo(n) {}"#, - span!(31, 33), UnsupportedRef + "let n = 0; foo(&n); fn foo(n) {}", + span!(15, 17), UnsupportedRef }; } #[test] fn test_template_strings() { - assert_parse!(r"pub fn main() { `hello \`` }"); - assert_parse!(r"pub fn main() { `hello \$` }"); + assert_parse!(r"`hello \``"); + assert_parse!(r"`hello \$`"); } #[test] fn test_wrong_arguments() { assert_errors! { - r#"pub fn main() { Some(1, 2) }"#, - span!(20, 26), BadArgumentCount { expected: 1, actual: 2, .. } + "Some(1, 2)", + span!(4, 10), BadArgumentCount { expected: 1, actual: 2, .. } }; assert_errors! { - r#"pub fn main() { None(1) }"#, - span!(20, 23), BadArgumentCount { expected: 0, actual: 1, .. } + "None(1)", + span!(4, 7), BadArgumentCount { expected: 0, actual: 1, .. } }; } #[test] fn test_bad_struct_declaration() { assert_errors! { - r#"struct Foo { a, b } pub fn main() { Foo { a: 12 } }"#, - span!(36, 49), LitObjectMissingField { field, .. } => { + "struct Foo { a, b } Foo { a: 12 }", + span!(20, 33), LitObjectMissingField { field, .. } => { assert_eq!(field.as_ref(), "b"); } }; assert_errors! { - r#"struct Foo { a, b } pub fn main() { Foo { not_field: 12 } }"#, - span!(42, 51), LitObjectNotField { field, .. } => { + "struct Foo { a, b } Foo { not_field: 12 }", + span!(26, 35), LitObjectNotField { field, .. } => { assert_eq!(field.as_ref(), "not_field"); } }; assert_errors! { - r#"pub fn main() { None(1) }"#, - span!(20, 23), BadArgumentCount { expected: 0, actual: 1, .. } + "None(1)", + span!(4, 7), BadArgumentCount { expected: 0, actual: 1, .. } }; } diff --git a/crates/rune/src/tests/compiler_literals.rs b/crates/rune/src/tests/compiler_literals.rs index a6896cf38..c6c999df7 100644 --- a/crates/rune/src/tests/compiler_literals.rs +++ b/crates/rune/src/tests/compiler_literals.rs @@ -3,33 +3,29 @@ prelude!(); use ErrorKind::*; #[test] -fn test_number_literals() { - assert_parse!(r#"pub fn main() { -9223372036854775808 }"#); - assert_parse!( - r#"pub fn main() { -0b1000000000000000000000000000000000000000000000000000000000000000 }"# - ); - assert_parse!( - r#"pub fn main() { 0b0111111111111111111111111111111111111111111111111111111111111111 }"# - ); +fn number_literals_oob() { + assert_parse!("-9223372036854775808"); + assert_parse!("-0b1000000000000000000000000000000000000000000000000000000000000000"); + assert_parse!("0b0111111111111111111111111111111111111111111111111111111111111111"); assert_errors! { - r#"pub fn main() { -0aardvark }"#, - span!(17, 26), BadNumberLiteral { .. } + "-0aardvark", + span!(1, 10), BadNumberLiteral { .. } }; assert_errors! { - r#"pub fn main() { -9223372036854775809 }"#, - span!(16, 36), BadSignedOutOfBounds { .. } + "-9223372036854775809", + span!(0, 20), BadSignedOutOfBounds { .. } }; - assert_parse!(r#"pub fn main() { 9223372036854775807 }"#); + assert_parse!("9223372036854775807"); assert_errors! { - r#"pub fn main() { 9223372036854775808 }"#, - span!(16, 35), BadSignedOutOfBounds { .. } + "9223372036854775808", + span!(0, 19), BadSignedOutOfBounds { .. } }; assert_errors! { - r#"pub fn main() { 0b1000000000000000000000000000000000000000000000000000000000000000 }"#, - span!(16, 82), BadSignedOutOfBounds { .. } + "0b1000000000000000000000000000000000000000000000000000000000000000", + span!(0, 66), BadSignedOutOfBounds { .. } }; } diff --git a/crates/rune/src/tests/compiler_paths.rs b/crates/rune/src/tests/compiler_paths.rs index 89ecdf867..1ba9c1dd2 100644 --- a/crates/rune/src/tests/compiler_paths.rs +++ b/crates/rune/src/tests/compiler_paths.rs @@ -27,7 +27,7 @@ fn test_super_self_crate_mod() { fn root() { 0b1 } - pub fn main() { Foo::foo() } + Foo::foo() }; assert_eq!(out, 0b111111); } @@ -49,7 +49,7 @@ fn test_super_use() { const VALUE = 1; - pub fn main() { x::y::foo() } + x::y::foo() }; assert_eq!(out, 3); } diff --git a/crates/rune/src/tests/compiler_patterns.rs b/crates/rune/src/tests/compiler_patterns.rs index c97782c5f..2b143ec38 100644 --- a/crates/rune/src/tests/compiler_patterns.rs +++ b/crates/rune/src/tests/compiler_patterns.rs @@ -7,12 +7,9 @@ fn illegal_pattern_in_match() -> rune::support::Result<()> { assert_errors! { r#" struct Foo { bar, baz } - - pub fn main() { - match () { Foo { } => {} } - } + match () { Foo {} => {} } "#, - span!(81, 88), PatternMissingFields { fields, .. } => { + span!(52, 58), PatternMissingFields { fields, .. } => { assert_eq!(fields.len(), 2); assert_eq!(fields[0].as_ref(), "bar"); assert_eq!(fields[1].as_ref(), "baz"); @@ -22,12 +19,9 @@ fn illegal_pattern_in_match() -> rune::support::Result<()> { assert_errors! { r#" struct Foo { bar, baz } - - pub fn main() { - match () { Foo { bar } => {} } - } + match () { Foo { bar } => {} } "#, - span!(81, 92), PatternMissingFields { fields, .. } => { + span!(52, 63), PatternMissingFields { fields, .. } => { assert_eq!(fields.len(), 1); assert_eq!(fields[0].as_ref(), "baz"); } diff --git a/crates/rune/src/tests/compiler_use.rs b/crates/rune/src/tests/compiler_use.rs index 37caed528..1724ce65c 100644 --- a/crates/rune/src/tests/compiler_use.rs +++ b/crates/rune/src/tests/compiler_use.rs @@ -13,12 +13,8 @@ fn test_import_cycle() { } use self::a::Foo; - - pub fn main() { - Foo - } "#, - span!(244, 247), ImportCycle { .. } + span!(49, 69), ImportCycle { .. } }; assert_errors! { diff --git a/crates/rune/src/tests/compiler_visibility.rs b/crates/rune/src/tests/compiler_visibility.rs index e84bfbcfd..36cec3e55 100644 --- a/crates/rune/src/tests/compiler_visibility.rs +++ b/crates/rune/src/tests/compiler_visibility.rs @@ -15,9 +15,7 @@ fn test_working_visibility() { pub fn visible() { b::hidden() } } - pub fn main() { - a::visible() - } + a::visible() }; assert_eq!(output, 42); @@ -58,7 +56,7 @@ fn test_hidden_reexport() { pub fn test() { Foo } } - pub fn main() { b::test() } + b::test() "#, span, NotVisible { .. } => { assert_eq!(span, span!(107, 110)); @@ -85,9 +83,7 @@ fn test_indirect_access() { } } - pub fn main() { - d::e::test().0 - } + d::e::test().0 }; assert_eq!(result, 2); @@ -119,9 +115,7 @@ fn test_rust_example() { } } - pub fn main() { - submodule::my_method(); - } + submodule::my_method(); }; } @@ -134,9 +128,7 @@ fn test_access_super() { pub fn test() { let _ = super::Test; 1 } } - pub fn main() { - c::test() - } + c::test() }; assert_eq!(value, 1); @@ -145,9 +137,7 @@ fn test_access_super() { mod a { pub(super) fn test() { 1 } } mod b { pub fn test() { crate::a::test() } } - pub fn main() { - b::test() - } + b::test() }; assert_eq!(value, 1); diff --git a/crates/rune/src/tests/compiler_warnings.rs b/crates/rune/src/tests/compiler_warnings.rs index 56360fda4..5fb4213d8 100644 --- a/crates/rune/src/tests/compiler_warnings.rs +++ b/crates/rune/src/tests/compiler_warnings.rs @@ -5,15 +5,15 @@ use diagnostics::WarningDiagnosticKind::*; #[test] fn test_let_pattern_might_panic() { assert_warnings! { - r#"pub fn main() { let [0, 1, 3] = []; }"#, - span!(20, 29), LetPatternMightPanic { context: Some(span!(14, 37)), .. } + "let [0, 1, 3] = [];", + span!(4, 13), LetPatternMightPanic { context: Some(span!(0, 19)), .. } }; } #[test] fn test_template_without_variables() { assert_warnings! { - r#"pub fn main() { `Hello World` }"#, - span!(16, 29), TemplateWithoutExpansions { context: Some(span!(14, 31)), .. } + "`Hello World`", + span!(0, 13), TemplateWithoutExpansions { context: Some(span!(0, 13)), .. } }; } diff --git a/crates/rune/src/tests/core_macros.rs b/crates/rune/src/tests/core_macros.rs index 791a1e377..d69a8d901 100644 --- a/crates/rune/src/tests/core_macros.rs +++ b/crates/rune/src/tests/core_macros.rs @@ -2,7 +2,7 @@ prelude!(); macro_rules! test_case { ($($tt:tt)*) => { - let out: String = rune!(pub fn main() { format!($($tt)*) }); + let out: String = rune!(format!($($tt)*)); assert_eq!(format!($($tt)*), out); } } @@ -10,25 +10,17 @@ macro_rules! test_case { #[test] fn test_asserts() { let _: () = rune!( - pub fn main() { - assert!(true) - } + assert!(true); ); let _: () = rune!( - pub fn main() { - assert_eq!(1 + 1, 2) - } + assert_eq!(1 + 1, 2); ); } #[test] fn test_stringify() { - let out: String = rune!( - pub fn main() { - stringify!(assert_eq!(1 + 1, 2)) - } - ); + let out: String = rune!(stringify!(assert_eq!(1 + 1, 2))); assert_eq!("assert_eq ! ( 1 + 1 , 2 )", out); } @@ -47,11 +39,7 @@ fn test_format() { test_case!("Hello, {1} {0}", "John", "Doe"); test_case!("Hello, {} {0} {}", "John", "Doe"); - let out: String = rune!( - pub fn main() { - format!("Hello, {}" + " {0} {}", "John", "Doe") - } - ); + let out: String = rune!(format!("Hello, {}" + " {0} {}", "John", "Doe")); assert_eq!(format!("Hello, {} {0} {}", "John", "Doe"), out); } diff --git a/crates/rune/src/tests/debug_fmt.rs b/crates/rune/src/tests/debug_fmt.rs index 7a02902d8..2003f01a2 100644 --- a/crates/rune/src/tests/debug_fmt.rs +++ b/crates/rune/src/tests/debug_fmt.rs @@ -22,32 +22,34 @@ fn make_native_module() -> Result { module.ty::()?; module.function_meta(NativeStructWithProtocol::debug_fmt)?; module.ty::()?; - Ok(module) } #[test] fn test_with_debug_fmt() { let t1 = NativeStructWithProtocol; - assert_eq!( - rune_n! { - make_native_module().expect("failed making native module"), - (t1, ), - String => - pub fn main(v) { format!("{:?}", v) } - }, - "NativeStructWithProtocol" - ); + + let m = make_native_module().unwrap(); + + let s: String = rune_n! { + mod m, + (t1,), + pub fn main(v) { format!("{v:?}") } + }; + + assert_eq!(s, "NativeStructWithProtocol"); } #[test] fn test_without_debug_fmt() { let t1 = NativeStructWithoutProtocol; - let result = rune_n! { - make_native_module().expect("failed making native module"), - (t1, ), - String => - pub fn main(v) { format!("{:?}", v) } + + let m = make_native_module().unwrap(); + + let result: String = rune_n! { + mod m, + (t1,), + pub fn main(v) { format!("{v:?}") } }; assert!( diff --git a/crates/rune/src/tests/destructuring.rs b/crates/rune/src/tests/destructuring.rs index dcefe1d48..ee0f93ed9 100644 --- a/crates/rune/src/tests/destructuring.rs +++ b/crates/rune/src/tests/destructuring.rs @@ -9,34 +9,30 @@ macro_rules! test_case { a + b } - pub fn main() { - let n = 0; + let n = 0; - for (a, b) in [(1, 2), (2, 3), (3, 4)] { - n += foo($($st)*); - } - - n + for (a, b) in [(1, 2), (2, 3), (3, 4)] { + n += foo($($st)*); } + + n }; assert_eq!(out, 15); let out: i64 = rune! { $($($extra)*)? - pub fn main() { - let foo = |$($ds)*| { - a + b - }; - - let n = 0; + let foo = |$($ds)*| { + a + b + }; - for (a, b) in [(1, 2), (2, 3), (3, 4)] { - n += foo($($st)*); - } + let n = 0; - n + for (a, b) in [(1, 2), (2, 3), (3, 4)] { + n += foo($($st)*); } + + n }; assert_eq!(out, 15); } diff --git a/crates/rune/src/tests/external_match.rs b/crates/rune/src/tests/external_match.rs index e057aecb0..9a8838102 100644 --- a/crates/rune/src/tests/external_match.rs +++ b/crates/rune/src/tests/external_match.rs @@ -22,41 +22,37 @@ fn struct_match() { let e = Struct { a: 40, b: 41 }; - assert_eq!( - rune_n! { - &m, - (e,), - i64 => pub fn main(v) { match v { Struct { .. } => 2, _ => 0 } } - }, - 2 - ); - - assert_eq!( - rune_n! { - &m, - (e,), - i64 => pub fn main(v) { match v { Struct { a, .. } => a, _ => 0 } } - }, - 40 - ); - - assert_eq!( - rune_n! { - &m, - (e,), - i64 => pub fn main(v) { match v { Struct { b, .. } => b, _ => 0 } } - }, - 41 - ); - - assert_eq!( - rune_n! { - &m, - (e,), - i64 => pub fn main(v) { match v { Struct { a, b } => a + b, _ => 0 } } - }, - 81 - ); + let n: u32 = rune_n! { + mod m, + (e,), + pub fn main(v) { match v { Struct { .. } => 2, _ => 0 } } + }; + + assert_eq!(n, 2); + + let n: u32 = rune_n! { + mod m, + (e,), + pub fn main(v) { match v { Struct { a, .. } => a, _ => 0 } } + }; + + assert_eq!(n, 40); + + let n: u32 = rune_n! { + mod m, + (e,), + pub fn main(v) { match v { Struct { b, .. } => b, _ => 0 } } + }; + + assert_eq!(n, 41); + + let n: u32 = rune_n! { + mod m, + (e,), + pub fn main(v) { match v { Struct { a, b } => a + b, _ => 0 } } + }; + + assert_eq!(n, 81); } #[test] @@ -81,36 +77,31 @@ fn enum_match() { ($expected:ident, $other:ident) => {{ let e = Enum::$expected; - assert_eq!( - rune_n! { - &m, - (e,), - i64 => pub fn main(v) { match v { Enum::$expected => 1, Enum::$other => 2, _ => 0 } } - }, - 1 - ); - - // TODO: Eventually we want this to be fine - we want the `{ .. }` - // pattern to match *any* kind of enum. - // assert_eq!( - // rune_n! { - // &m, - // (e,), - // i64 => pub fn main(v) { match v { Enum::$expected { .. } => 1, Enum::$other => 2, _ => 0 } } - // }, - // 1 - // ); + let n: u32 = rune_n! { + mod m, + (e,), + pub fn main(v) { match v { Enum::$expected => 1, Enum::$other => 2, _ => 0 } } + }; + + assert_eq!(n, 1); + + let n: u32 = rune_n! { + mod m, + (e,), + pub fn main(v) { match v { Enum::$expected { .. } => 1, Enum::$other => 2, _ => 0 } } + }; + + assert_eq!(n, 1); let e = Enum::$other; - assert_eq!( - rune_n! { - &m, - (e,), - i64 => pub fn main(v) { match v { Enum::$expected => 1, Enum::$other => 2, _ => 0 } } - }, - 2 - ); + let n: u32 = rune_n! { + mod m, + (e,), + pub fn main(v) { match v { Enum::$expected => 1, Enum::$other => 2, _ => 0 } } + }; + + assert_eq!(n, 2); }} } diff --git a/crates/rune/src/tests/iterator.rs b/crates/rune/src/tests/iterator.rs index 273593ff6..073175962 100644 --- a/crates/rune/src/tests/iterator.rs +++ b/crates/rune/src/tests/iterator.rs @@ -7,9 +7,7 @@ fn test_range_iter() { let values: Vec = rune! { use std::iter::range; - pub fn main() { - range(0, 100).map(|n| n * 2).filter(|n| n % 3 == 0).collect::() - } + range(0, 100).map(|n| n * 2).filter(|n| n % 3 == 0).collect::() }; assert_eq!( @@ -26,9 +24,7 @@ fn test_rev() { let values: Vec = rune! { use std::iter::range; - pub fn main() { - range(0, 100).map(|n| n * 2).filter(|n| n % 3 == 0).rev().collect::() - } + range(0, 100).map(|n| n * 2).filter(|n| n % 3 == 0).rev().collect::() }; let expected = (0..100) @@ -45,23 +41,21 @@ fn test_next_back() { let _: () = rune! { const SOURCE = [1, 2, 3, "foo"]; - pub fn main() { - let it = SOURCE.iter().rev(); - let v = Vec::new(); - - while let Some(n) = it.next_back() { - v.push(n); - } + let it = SOURCE.iter().rev(); + let v = Vec::new(); - assert_eq!(v, SOURCE); + while let Some(n) = it.next_back() { + v.push(n); } + + assert_eq!(v, SOURCE); }; } #[test] fn test_object_rev_error() { assert_vm_error!( - r#"pub fn main() { #{}.iter().rev() }"#, + "#{}.iter().rev()", MissingInstanceFunction { hash: rune::hash!(::std::object::Iter.rev), .. } => { } ); @@ -70,9 +64,7 @@ fn test_object_rev_error() { #[test] fn test_chain() { let values: Vec = rune! { - pub fn main() { - [1, 2].iter().rev().chain([3, 4].iter()).collect::() - } + [1, 2].iter().rev().chain([3, 4].iter()).collect::() }; assert_eq!(values, vec![2, 1, 3, 4]) @@ -81,11 +73,9 @@ fn test_chain() { #[test] fn test_enumerate() { let values: Vec<(i64, i64)> = rune! { - pub fn main() { - let it = [1, 2].iter().rev().chain([3, 4].iter()).enumerate(); - assert_eq!(it.next_back(), Some((3, 4))); - it.collect::() - } + let it = [1, 2].iter().rev().chain([3, 4].iter()).enumerate(); + assert_eq!(it.next_back(), Some((3, 4))); + it.collect::() }; assert_eq!(values, vec![(0, 2), (1, 1), (2, 3)]) @@ -94,9 +84,7 @@ fn test_enumerate() { #[test] fn test_option_iter() { let values: Vec = rune! { - pub fn main() { - Some(1).iter().chain(None.iter()).chain(Some(3).iter()).collect::() - } + Some(1).iter().chain(None.iter()).chain(Some(3).iter()).collect::() }; assert_eq!(values, vec![1, 3]) @@ -107,20 +95,18 @@ fn test_peekable_take() { let actual: Vec = rune! { use std::iter::range; - pub fn main() { - let it = range(1, 100).take(40).peekable(); - let out = []; + let it = range(1, 100).take(40).peekable(); + let out = []; - while let Some(n) = it.next() { - out.push(n); + while let Some(n) = it.next() { + out.push(n); - if it.peek().is_some() { - out.push(0); - } + if it.peek().is_some() { + out.push(0); } - - out } + + out }; let mut it = (1..100).take(40).peekable(); @@ -139,18 +125,16 @@ fn test_flat_map() { let actual: Vec = rune! { use std::iter::range; - pub fn main() { - let it = range(1, 10).flat_map(|n| range(1, n + 1)); + let it = range(1, 10).flat_map(|n| range(1, n + 1)); - let out = []; + let out = []; - while let (Some(a), Some(b)) = (it.next(), it.next_back()) { - out.push(a); - out.push(b); - } - - out + while let (Some(a), Some(b)) = (it.next(), it.next_back()) { + out.push(a); + out.push(b); } + + out }; let mut it = (1..10).flat_map(|n| 1..=n); diff --git a/crates/rune/src/tests/option.rs b/crates/rune/src/tests/option.rs index 1a808ab47..94d6ba277 100644 --- a/crates/rune/src/tests/option.rs +++ b/crates/rune/src/tests/option.rs @@ -4,43 +4,27 @@ use VmErrorKind::*; #[test] fn test_map() { - let out: Option = rune! { - pub fn main() { - Some(1).map(|v| v + 1) - } - }; + let out: Option = rune!(Some(1).map(|v| v + 1)); assert_eq!(out, Some(2)) } #[test] fn test_and_then() { - let out: Option = rune! { - pub fn main() { - Some(1).and_then(|v| Some(v + 1)) - } - }; + let out: Option = rune!(Some(1).and_then(|v| Some(v + 1))); assert_eq!(out, Some(2)) } #[test] fn test_expect_some() { - let out: i32 = rune! { - pub fn main() { - Some(1).expect("Some") - } - }; + let out: i32 = rune!(Some(1).expect("Some")); assert_eq!(out, 1); } #[test] fn test_expect() { assert_vm_error!( - r#" - pub fn main() { - None.expect("None") - } - "#, - Panic { reason} => { + "None.expect(\"None\")", + Panic { reason } => { assert_eq!(reason.to_string(), "None") } ); @@ -48,22 +32,14 @@ fn test_expect() { #[test] fn test_unwrap_some() { - let out: i32 = rune! { - pub fn main() { - Some(1).unwrap() - } - }; + let out: i32 = rune!(Some(1).unwrap()); assert_eq!(out, 1); } #[test] fn test_unwrap() { assert_vm_error!( - r#" - pub fn main() { - None.unwrap() - } - "#, + "None.unwrap()", Panic { reason} => { assert_eq!(reason.to_string(), "Called `Option::unwrap()` on a `None` value") } diff --git a/crates/rune/src/tests/patterns.rs b/crates/rune/src/tests/patterns.rs index f80f5ce6a..afa3fba74 100644 --- a/crates/rune/src/tests/patterns.rs +++ b/crates/rune/src/tests/patterns.rs @@ -7,11 +7,7 @@ use VmErrorKind::*; fn test_bad_pattern() { // Attempting to assign to an unmatched pattern leads to a panic. assert_vm_error!( - r#" - pub fn main() { - let [] = [1, 2, 3]; - } - "#, + "let [] = [1, 2, 3];", Panic { reason } => { assert_eq!(reason.to_string(), "pattern did not match"); } @@ -34,14 +30,12 @@ fn test_const_in_pattern() { }} }}; - pub fn main() {{ - let value = {pat1}; - let a = match value {{ PAT => 1, _ => 5 }}; - let b = match value {{ PAT2 => 2, _ => 6 }}; - let c = match value {{ PAT3 => 3, _ => 7 }}; - let d = match value {{ PAT4 => 4, _ => 8 }}; - (a, b, c, d) - }} + let value = {pat1}; + let a = match value {{ PAT => 1, _ => 5 }}; + let b = match value {{ PAT2 => 2, _ => 6 }}; + let c = match value {{ PAT3 => 3, _ => 7 }}; + let d = match value {{ PAT4 => 4, _ => 8 }}; + (a, b, c, d) "#, pat1 = $pat1, pat2 = $pat2, diff --git a/crates/rune/src/tests/range.rs b/crates/rune/src/tests/range.rs index 4277ba691..0010ddaa6 100644 --- a/crates/rune/src/tests/range.rs +++ b/crates/rune/src/tests/range.rs @@ -6,15 +6,15 @@ use VmErrorKind::*; #[test] fn unsupported_compile_range() { assert_errors! { - "pub fn main() { 'a'..= }", - span!(16, 22), Custom { error } => { + "'a'..=", + span!(0, 6), Custom { error } => { assert_eq!(error.to_string(), "Unsupported range, you probably want `..` instead of `..=`") } }; assert_errors! { - "pub fn main() { ..= }", - span!(16, 19), Custom { error } => { + "..=", + span!(0, 3), Custom { error } => { assert_eq!(error.to_string(), "Unsupported range, you probably want `..` instead of `..=`") } }; @@ -23,14 +23,14 @@ fn unsupported_compile_range() { #[test] fn unsupported_iter_range() { assert_vm_error!( - r#"pub fn main() { (1.0..).iter() }"#, + "(1.0..).iter()", UnsupportedIterRangeFrom { start } => { assert_eq!(start, f64::type_info()); } ); assert_vm_error!( - r#"pub fn main() { (1.0..2.0).iter() }"#, + "(1.0..2.0).iter()", UnsupportedIterRange { start, end } => { assert_eq!(start, f64::type_info()); assert_eq!(end, f64::type_info()); @@ -38,7 +38,7 @@ fn unsupported_iter_range() { ); assert_vm_error!( - r#"pub fn main() { (1.0..=2.0).iter() }"#, + "(1.0..=2.0).iter()", UnsupportedIterRangeInclusive { start, end } => { assert_eq!(start, f64::type_info()); assert_eq!(end, f64::type_info()); @@ -46,7 +46,7 @@ fn unsupported_iter_range() { ); assert_vm_error!( - r#"pub fn main() { for _ in 1.0.. {} }"#, + "for _ in 1.0..{}", UnsupportedIterRangeFrom { start } => { assert_eq!(start, f64::type_info()); } diff --git a/crates/rune/src/tests/result.rs b/crates/rune/src/tests/result.rs index b1fe59d67..3e7bf5946 100644 --- a/crates/rune/src/tests/result.rs +++ b/crates/rune/src/tests/result.rs @@ -5,29 +5,18 @@ prelude!(); use VmErrorKind::*; #[test] -fn test_expect() { - assert_vm_error!(r#" - pub fn main() { - Err("Error").expect("Err('Error')") - } - "#, +fn panics() { + assert_vm_error!( + "Err(\"Error\").expect(\"Err('Error')\")", Panic { reason } => { assert_eq!(reason.to_string(), "Err('Error'): \"Error\"") } ); -} -#[test] -fn test_unwrap() { assert_vm_error!( - r#" - pub fn main() { - Err("Error").unwrap() - } - "#, + "Err(\"Error\").unwrap()", Panic { reason } => { - assert_eq!(reason.to_string(), - "Called `Result::unwrap()` on an `Err` value: \"Error\"") + assert_eq!(reason.to_string(), "Called `Result::unwrap()` on an `Err` value: \"Error\"") } ); } diff --git a/crates/rune/src/tests/tuple.rs b/crates/rune/src/tests/tuple.rs index 3c5b83430..3eeeb20f3 100644 --- a/crates/rune/src/tests/tuple.rs +++ b/crates/rune/src/tests/tuple.rs @@ -20,10 +20,10 @@ fn make_module() -> Result { fn test_tuple_ownership() { let m = make_module().expect("Failed to make module"); - rune_n! { - &m, + let _: () = rune_n! { + mod m, (), - () => pub fn main() { + pub fn main() { let a = []; let b = []; let tuple = (a, b); @@ -34,10 +34,10 @@ fn test_tuple_ownership() { } }; - rune_n! { - &m, + let _: () = rune_n! { + mod m, (), - () => pub fn main() { + pub fn main() { let a = []; let b = []; let vec = [a, b]; diff --git a/crates/rune/src/tests/type_name_native.rs b/crates/rune/src/tests/type_name_native.rs index 2e69c99ce..24a9f5b20 100644 --- a/crates/rune/src/tests/type_name_native.rs +++ b/crates/rune/src/tests/type_name_native.rs @@ -28,53 +28,57 @@ fn make_native_module() -> Result { #[test] fn test_struct() { let t1 = NativeStruct(1); - assert_eq!( - rune_n! { - make_native_module().expect("failed making native module"), - (t1, ), - String => - pub fn main(v) { std::any::type_name_of_val(v) } - }, - "::native_crate::NativeStruct" - ); + + let m = make_native_module().expect("failed making native module"); + + let s: String = rune_n! { + mod m, + (t1,), + pub fn main(v) { std::any::type_name_of_val(v) } + }; + + assert_eq!(s, "::native_crate::NativeStruct"); } #[test] fn test_fn() { - assert_eq!( - rune_n! { - make_native_module().expect("failed making native module"), - (), - String => pub fn main() { std::any::type_name_of_val(native_crate::native_fn) } - }, - "::std::ops::Function" - ); + let m = make_native_module().expect("failed making native module"); + + let s: String = rune_n! { + mod m, + (), + pub fn main() { std::any::type_name_of_val(native_crate::native_fn) } + }; + + assert_eq!(s, "::std::ops::Function"); } #[test] fn test_inst_fn() { - assert_eq!( - rune_n! { - make_native_module().expect("failed making native module"), - (), - String => - pub fn main() { - std::any::type_name_of_val(native_crate::NativeStruct::instance_fn) - } - }, - "::std::ops::Function" - ); + let m = make_native_module().expect("failed making native module"); + + let s: String = rune_n! { + mod m, + (), + pub fn main() { + std::any::type_name_of_val(native_crate::NativeStruct::instance_fn) + } + }; + + assert_eq!(s, "::std::ops::Function"); } #[test] fn test_field_fn() { let t1 = NativeStruct(1); - assert_eq!( - rune_n! { - make_native_module().expect("failed making native module"), - (t1, ), - String => pub fn main(val) { std::any::type_name_of_val(val.x) } - }, - "::std::u64" - ); + + let m = make_native_module().expect("failed making native module"); + + let s: String = rune_n! { + mod m, + (t1, ), + pub fn main(val) { std::any::type_name_of_val(val.x) } + }; + + assert_eq!(s, "::std::u64"); } diff --git a/crates/rune/src/tests/vm_arithmetic.rs b/crates/rune/src/tests/vm_arithmetic.rs index d479a8329..ef3bd5593 100644 --- a/crates/rune/src/tests/vm_arithmetic.rs +++ b/crates/rune/src/tests/vm_arithmetic.rs @@ -12,118 +12,118 @@ macro_rules! op_tests { }; (@binary $ty:ty, $lhs:literal, $op:tt, $rhs:literal, $out:expr) => { - let out: $ty = rune!(pub fn main() { let a = $lhs; let b = $rhs; a $op b}); + let out: $ty = rune!(let a = $lhs; let b = $rhs; a $op b); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"pub fn main() {{ let a = {lhs}; let b = {rhs}; a {op}= b; a }}"#, + r#"let a = {lhs}; let b = {rhs}; a {op}= b; a"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"struct Foo {{ padding, field }}; pub fn main() {{ let a = Foo{{ padding: 0, field: {lhs} }}; let b = {rhs}; a.field {op}= b; a.field }}"#, + r#"struct Foo {{ padding, field }}; let a = Foo{{ padding: 0, field: {lhs} }}; let b = {rhs}; a.field {op}= b; a.field"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"enum Enum {{ Foo {{ padding, field }} }}; pub fn main() {{ let a = Enum::Foo {{ padding: 0, field: {lhs} }}; let b = {rhs}; a.field {op}= b; a.field }}"#, + r#"enum Enum {{ Foo {{ padding, field }} }}; let a = Enum::Foo {{ padding: 0, field: {lhs} }}; let b = {rhs}; a.field {op}= b; a.field"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"pub fn main() {{ let a = #{{ padding: 0, field: {lhs} }}; let b = {rhs}; a.field {op}= b; a.field }}"#, + r#"let a = #{{ padding: 0, field: {lhs} }}; let b = {rhs}; a.field {op}= b; a.field"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"pub fn main() {{ let a = (0, {lhs}); let b = {rhs}; a.1 {op}= b; a.1 }}"#, + r#"let a = (0, {lhs}); let b = {rhs}; a.1 {op}= b; a.1"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"struct Foo(padding, a); pub fn main() {{ let a = Foo(0, {lhs}); let b = {rhs}; a.1 {op}= b; a.1 }}"#, + r#"struct Foo(padding, a); let a = Foo(0, {lhs}); let b = {rhs}; a.1 {op}= b; a.1"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"enum Enum {{ Foo(padding, a) }}; pub fn main() {{ let a = Enum::Foo(0, {lhs}); let b = {rhs}; a.1 {op}= b; a.1 }}"#, + r#"enum Enum {{ Foo(padding, a) }}; let a = Enum::Foo(0, {lhs}); let b = {rhs}; a.1 {op}= b; a.1"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"pub fn main() {{ let a = Ok({lhs}); let b = {rhs}; a.0 {op}= b; a.0 }}"#, + r#"let a = Ok({lhs}); let b = {rhs}; a.0 {op}= b; a.0"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"pub fn main() {{ let a = Some({lhs}); let b = {rhs}; a.0 {op}= b; a.0 }}"#, + r#"let a = Some({lhs}); let b = {rhs}; a.0 {op}= b; a.0"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), )); assert_eq!(out, $out); }; (@unary $ty:ty, $op:tt, $lhs:literal, $out:expr) => { - let out: $ty = rune!(pub fn main() { let a = $lhs; $op a}); + let out: $ty = rune!(let a = $lhs; $op a); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"pub fn main() {{ let a = {lhs}; {op} a }}"#, + r#"let a = {lhs}; {op} a"#, lhs = stringify!($lhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"struct Foo {{ padding, field }}; pub fn main() {{ let a = Foo{{ padding: 0, field: {lhs} }}; {op} a.field }}"#, + r#"struct Foo {{ padding, field }}; let a = Foo{{ padding: 0, field: {lhs} }}; {op} a.field"#, lhs = stringify!($lhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"enum Enum {{ Foo {{ padding, field }} }}; pub fn main() {{ let a = Enum::Foo {{ padding: 0, field: {lhs} }}; {op} a.field }}"#, + r#"enum Enum {{ Foo {{ padding, field }} }}; let a = Enum::Foo {{ padding: 0, field: {lhs} }}; {op} a.field"#, lhs = stringify!($lhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"pub fn main() {{ let a = #{{ padding: 0, field: {lhs} }}; {op} a.field }}"#, + r#"let a = #{{ padding: 0, field: {lhs} }}; {op} a.field"#, lhs = stringify!($lhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"pub fn main() {{ let a = (0, {lhs}); {op} a.1 }}"#, + r#"let a = (0, {lhs}); {op} a.1"#, lhs = stringify!($lhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"struct Foo(padding, a); pub fn main() {{ let a = Foo(0, {lhs}); {op} a.1 }}"#, + r#"struct Foo(padding, a); let a = Foo(0, {lhs}); {op} a.1"#, lhs = stringify!($lhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"enum Enum {{ Foo(padding, a) }}; pub fn main() {{ let a = Enum::Foo(0, {lhs}); {op} a.1 }}"#, + r#"enum Enum {{ Foo(padding, a) }}; let a = Enum::Foo(0, {lhs}); {op} a.1"#, lhs = stringify!($lhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"pub fn main() {{ let a = Ok({lhs}); {op} a.0 }}"#, + r#"let a = Ok({lhs}); {op} a.0"#, lhs = stringify!($lhs), op = stringify!($op), )); assert_eq!(out, $out); let out: $ty = eval(&format!( - r#"pub fn main() {{ let a = Some({lhs}); {op} a.0 }}"#, + r#"let a = Some({lhs}); {op} a.0"#, lhs = stringify!($lhs), op = stringify!($op), )); assert_eq!(out, $out); @@ -134,7 +134,7 @@ macro_rules! error_test { ($lhs:literal $op:tt $rhs:literal = $error:ident) => { assert_vm_error!( &format!( - r#"pub fn main() {{ let a = {lhs}; let b = {rhs}; a {op} b; }}"#, + r#"let a = {lhs}; let b = {rhs}; a {op} b;"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), ), $error => {} @@ -142,7 +142,7 @@ macro_rules! error_test { assert_vm_error!( &format!( - r#"pub fn main() {{ let a = {lhs}; let b = {rhs}; a {op}= b; }}"#, + r#"let a = {lhs}; let b = {rhs}; a {op}= b;"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), ), $error => {} @@ -150,7 +150,7 @@ macro_rules! error_test { assert_vm_error!( &format!( - r#"pub fn main() {{ let a = #{{ padding: 0, field: {lhs} }}; let b = {rhs}; a.field {op}= b; }}"#, + r#"let a = #{{ padding: 0, field: {lhs} }}; let b = {rhs}; a.field {op}= b;"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), ), $error => {} @@ -158,7 +158,7 @@ macro_rules! error_test { assert_vm_error!( &format!( - r#"pub fn main() {{ let a = (0, {lhs}); let b = {rhs}; a.1 {op}= b; }}"#, + r#"let a = (0, {lhs}); let b = {rhs}; a.1 {op}= b;"#, lhs = stringify!($lhs), rhs = stringify!($rhs), op = stringify!($op), ), $error => {} diff --git a/crates/rune/src/tests/vm_assign_exprs.rs b/crates/rune/src/tests/vm_assign_exprs.rs index 4a97461e7..265570395 100644 --- a/crates/rune/src/tests/vm_assign_exprs.rs +++ b/crates/rune/src/tests/vm_assign_exprs.rs @@ -4,14 +4,12 @@ prelude!(); fn test_assign_assign_exprs() { let out: (i64, (), ()) = eval( r#" - pub fn main() { - let a = #{b: #{c: #{d: 1}}}; - let b = 2; - let c = 3; + let a = #{b: #{c: #{d: 1}}}; + let b = 2; + let c = 3; - c = b = a.b.c = 4; - (a.b.c, b, c) - } + c = b = a.b.c = 4; + (a.b.c, b, c) "#, ); assert_eq!(out, (4, (), ())); diff --git a/crates/rune/src/tests/vm_async_block.rs b/crates/rune/src/tests/vm_async_block.rs index 18434b66a..aab1ff20a 100644 --- a/crates/rune/src/tests/vm_async_block.rs +++ b/crates/rune/src/tests/vm_async_block.rs @@ -8,10 +8,8 @@ fn test_async_block() { output } - pub async fn main() { - let value = 42; - foo(async { value }).await / foo(async { 2 }).await - } + let value = 42; + foo(async { value }).await / foo(async { 2 }).await }; assert_eq!(out, 21); } diff --git a/crates/rune/src/tests/vm_blocks.rs b/crates/rune/src/tests/vm_blocks.rs index 8884aac86..a758d0f4d 100644 --- a/crates/rune/src/tests/vm_blocks.rs +++ b/crates/rune/src/tests/vm_blocks.rs @@ -3,11 +3,9 @@ prelude!(); #[test] fn test_anonymous_type_precedence() { let out: i64 = rune! { - pub fn main() { - fn a() { 1 } - fn b() { return a(); fn a() { 2 } } - a() + b() - } + fn a() { 1 } + fn b() { return a(); fn a() { 2 } } + a() + b() }; assert_eq!(out, 3); } diff --git a/crates/rune/src/tests/vm_closures.rs b/crates/rune/src/tests/vm_closures.rs index 8f6db1825..ca278b63f 100644 --- a/crates/rune/src/tests/vm_closures.rs +++ b/crates/rune/src/tests/vm_closures.rs @@ -2,8 +2,7 @@ prelude!(); #[test] fn test_closure_in_lit_vec() -> VmResult<()> { - let ret: VecTuple<(i64, Function, Function, i64)> = - eval(r#"pub fn main() { let a = 4; [0, || 2, || 4, 3] }"#); + let ret: VecTuple<(i64, Function, Function, i64)> = eval(r#"let a = 4; [0, || 2, || 4, 3]"#); let (start, first, second, end) = ret.0; assert_eq!(0, start); @@ -15,8 +14,7 @@ fn test_closure_in_lit_vec() -> VmResult<()> { #[test] fn test_closure_in_lit_tuple() -> VmResult<()> { - let ret: (i64, Function, Function, i64) = - eval(r#"pub fn main() { let a = 4; (0, || 2, || a, 3) }"#); + let ret: (i64, Function, Function, i64) = eval(r#"let a = 4; (0, || 2, || a, 3)"#); let (start, first, second, end) = ret; assert_eq!(0, start); @@ -36,7 +34,7 @@ fn test_closure_in_lit_object() -> Result<()> { d: i64, } - let proxy: Proxy = eval("pub fn main() { let a = 4; #{a: 0, b: || 2, c: || a, d: 3} }"); + let proxy: Proxy = eval("let a = 4; #{a: 0, b: || 2, c: || a, d: 3}"); assert_eq!(0, proxy.a); assert_eq!(2, proxy.b.call::(()).into_result()?); diff --git a/crates/rune/src/tests/vm_const_exprs.rs b/crates/rune/src/tests/vm_const_exprs.rs index 77f5dc315..6a8f9724a 100644 --- a/crates/rune/src/tests/vm_const_exprs.rs +++ b/crates/rune/src/tests/vm_const_exprs.rs @@ -3,27 +3,28 @@ prelude!(); macro_rules! test_op { ($ty:ty => $lhs:literal $op:tt $rhs:literal = $result:literal) => {{ let program = format!( - r#"const A = {lhs}; const B = {rhs}; const VALUE = A {op} B; pub fn main() {{ VALUE }}"#, - lhs = $lhs, rhs = $rhs, op = stringify!($op), + r#"const A = {lhs}; const B = {rhs}; const VALUE = A {op} B; VALUE"#, + lhs = $lhs, + rhs = $rhs, + op = stringify!($op), ); let out: $ty = eval(&program); assert_eq!( - out, - $result, + out, $result, concat!("expected ", stringify!($result), " out of program `{}`"), program ); - }} + }}; } #[test] fn test_const_values() { - let out: bool = rune!(const VALUE = true; pub fn main() { VALUE }); + let out: bool = rune!(const VALUE = true; VALUE); assert_eq!(out, true); - let out: String = rune!(const VALUE = "Hello World"; pub fn main() { VALUE }); + let out: String = rune!(const VALUE = "Hello World"; VALUE); assert_eq!(out, "Hello World"); let out: String = eval( @@ -33,7 +34,7 @@ fn test_const_values() { const A = 1; const B = 1.0; const C = true; - pub fn main() { VALUE } + VALUE "#, ); assert_eq!(out, "Hello World 1 1.0 true"); @@ -60,19 +61,20 @@ fn test_integer_ops() { macro_rules! test_float_op { ($ty:ty => $lhs:literal $op:tt $rhs:literal = $result:literal) => {{ let program = format!( - r#"const A = {lhs}.0; const B = {rhs}.0; const VALUE = A {op} B; pub fn main() {{ VALUE }}"#, - lhs = $lhs, rhs = $rhs, op = stringify!($op), + r#"const A = {lhs}.0; const B = {rhs}.0; const VALUE = A {op} B; VALUE"#, + lhs = $lhs, + rhs = $rhs, + op = stringify!($op), ); let out: $ty = eval(&program); assert_eq!( - out, - $result, + out, $result, concat!("expected ", stringify!($result), " out of program `{}`"), program ); - }} + }}; } #[test] @@ -93,22 +95,22 @@ fn test_float_ops() { #[test] fn test_const_collections() { - let object: Object = rune!(pub fn main() { VALUE } const VALUE = #{};); + let object: Object = rune!(fn main() { VALUE } const VALUE = #{}; main()); assert!(object.is_empty()); - let tuple: Box = rune!(pub fn main() { VALUE } const VALUE = ();); + let tuple: Box = rune!(fn main() { VALUE } const VALUE = (); main()); assert!(tuple.is_empty()); - let tuple: Box = rune!(pub fn main() { VALUE } const VALUE = ("Hello World",);); + let tuple: Box = rune!(fn main() { VALUE } const VALUE = ("Hello World",); main()); assert_eq!( Some("Hello World"), tuple.get_value::(0).unwrap().as_deref() ); - let vec: runtime::Vec = rune!(pub fn main() { VALUE } const VALUE = [];); + let vec: runtime::Vec = rune!(fn main() { VALUE } const VALUE = []; main()); assert!(vec.is_empty()); - let vec: runtime::Vec = rune!(pub fn main() { VALUE } const VALUE = ["Hello World"];); + let vec: runtime::Vec = rune!(fn main() { VALUE } const VALUE = ["Hello World"]; main()); assert_eq!( Some("Hello World"), vec.get_value::(0).unwrap().as_deref() @@ -131,7 +133,7 @@ fn test_more_complexity() { timeout }; - pub fn main() { VALUE } + VALUE }; assert_eq!(result, 1280); @@ -141,19 +143,19 @@ fn test_more_complexity() { fn test_if_else() { let result: i64 = rune! { const VALUE = { if true { 1 } else if true { 2 } else { 3 } }; - pub fn main() { VALUE } + VALUE }; assert_eq!(result, 1); let result: i64 = rune! { const VALUE = { if false { 1 } else if true { 2 } else { 3 } }; - pub fn main() { VALUE } + VALUE }; assert_eq!(result, 2); let result: i64 = rune! { const VALUE = { if false { 1 } else if false { 2 } else { 3 } }; - pub fn main() { VALUE } + VALUE }; assert_eq!(result, 3); } @@ -164,10 +166,12 @@ fn test_const_fn() { const VALUE = 2; const fn foo(n) { n + VALUE } - pub fn main() { + fn bar() { const VALUE = 1; foo(1 + 4 / 2 - VALUE) + foo(VALUE - 1) } + + bar() }; assert_eq!(result, 6); @@ -180,9 +184,7 @@ fn test_const_fn() { `foo ${n}` } - pub fn main() { - foo(`bar ${VALUE}`) - } + foo(`bar ${VALUE}`) "#, ); @@ -200,9 +202,7 @@ fn test_const_fn() { c } - pub fn main() { - VALUE - } + VALUE "#, ); @@ -230,9 +230,7 @@ fn test_const_fn_visibility() { const B = 2; } - pub fn main() { - b::out() - } + b::out() }; assert_eq!(result, 3); @@ -241,31 +239,25 @@ fn test_const_fn_visibility() { #[test] fn test_const_block() { let result: i64 = rune! { - pub fn main() { - let u = 2; - let value = const { 1 << test() }; - return value - u; - const fn test() { 32 } - } + let u = 2; + let value = const { 1 << test() }; + return value - u; + const fn test() { 32 } }; assert_eq!(result, (1i64 << 32) - 2); let result: String = rune! { - pub fn main() { - let var = "World"; - format!(const { "Hello {}" }, var) - } + let var = "World"; + format!(const { "Hello {}" }, var) }; assert_eq!(result, "Hello World"); let result: String = rune! { - pub fn main() { - let var = "World"; - return format!(const { FORMAT }, var); - const FORMAT = "Hello {}"; - } + let var = "World"; + return format!(const { FORMAT }, var); + const FORMAT = "Hello {}"; }; assert_eq!(result, "Hello World"); diff --git a/crates/rune/src/tests/vm_early_termination.rs b/crates/rune/src/tests/vm_early_termination.rs index be515908c..bf4d050ac 100644 --- a/crates/rune/src/tests/vm_early_termination.rs +++ b/crates/rune/src/tests/vm_early_termination.rs @@ -2,28 +2,28 @@ prelude!(); macro_rules! test_case { (($($k:tt)*), $field:tt, $index:tt, $($extra:tt)*) => { - let out: bool = rune!(pub fn main() { let m = $($k)*; m[return true]; false } $($extra)*); + let out: bool = rune!(fn main() { let m = $($k)*; m[return true]; false } $($extra)* main()); assert_eq!(out, true); - let out: bool = rune!(pub fn main() { let m = $($k)*; m[return true] = 0; false } $($extra)*); + let out: bool = rune!(fn main() { let m = $($k)*; m[return true] = 0; false } $($extra)* main()); assert_eq!(out, true); - let out: bool = rune!(pub fn main() { let m = $($k)*; m[$index] = return true; false } $($extra)*); + let out: bool = rune!(fn main() { let m = $($k)*; m[$index] = return true; false } $($extra)* main()); assert_eq!(out, true); - let out: bool = rune!(pub fn main() { let m = $($k)*; m.$field = return true; false } $($extra)*); + let out: bool = rune!(fn main() { let m = $($k)*; m.$field = return true; false } $($extra)* main()); assert_eq!(out, true); - let out: bool = rune!(pub fn main() { $($k)*[return true]; false } $($extra)*); + let out: bool = rune!(fn main() { $($k)*[return true]; false } $($extra)* main()); assert_eq!(out, true); - let out: bool = rune!(pub fn main() { $($k)*[return true] = 0; false } $($extra)*); + let out: bool = rune!(fn main() { $($k)*[return true] = 0; false } $($extra)* main()); assert_eq!(out, true); - let out: bool = rune!(pub fn main() { $($k)*[$index] = return true; false } $($extra)*); + let out: bool = rune!(fn main() { $($k)*[$index] = return true; false } $($extra)* main()); assert_eq!(out, true); - let out: bool = rune!(pub fn main() { $($k)*.$field = return true; false } $($extra)*); + let out: bool = rune!(fn main() { $($k)*.$field = return true; false } $($extra)* main()); assert_eq!(out, true); }; diff --git a/crates/rune/src/tests/vm_function.rs b/crates/rune/src/tests/vm_function.rs index 6eb2fa7b6..ad84bb2f1 100644 --- a/crates/rune/src/tests/vm_function.rs +++ b/crates/rune/src/tests/vm_function.rs @@ -9,19 +9,14 @@ fn test_function() { // ptr to dynamic function. let function: Function = rune! { fn foo(a, b) { a + b } - - pub fn main() { foo } + foo }; assert_eq!(function.call::((1i64, 3i64)).unwrap(), 4i64); assert!(function.call::((1i64,)).is_err()); // ptr to native function - let function: Function = rune!( - pub fn main() { - Vec::new - } - ); + let function: Function = rune!(Vec::new); let value: Vec = function.call(()).unwrap(); assert_eq!(value.len(), 0); @@ -29,7 +24,7 @@ fn test_function() { // ptr to dynamic function. let function: Function = rune! { enum Custom { A(a) } - pub fn main() { Custom::A } + Custom::A }; assert!(function.call::(()).into_result().is_err()); @@ -39,7 +34,7 @@ fn test_function() { // ptr to dynamic function. let function: Function = rune! { struct Custom(a); - pub fn main() { Custom } + Custom }; assert!(function.call::(()).into_result().is_err()); @@ -48,7 +43,7 @@ fn test_function() { // non-capturing closure == free function let function: Function = rune! { - pub fn main() { |a, b| a + b } + |a, b| a + b }; assert!(function.call::((1i64,)).into_result().is_err()); @@ -58,9 +53,9 @@ fn test_function() { // closure with captures let function: Function = run( &context, - r#"pub fn main(a, b) { || a + b }"#, - ["main"], + "pub fn main(a, b) { || a + b }", (1i64, 2i64), + false, ) .unwrap(); diff --git a/crates/rune/src/tests/vm_function_pointers.rs b/crates/rune/src/tests/vm_function_pointers.rs index 966c9e28a..c0fc659c3 100644 --- a/crates/rune/src/tests/vm_function_pointers.rs +++ b/crates/rune/src/tests/vm_function_pointers.rs @@ -6,24 +6,9 @@ prelude!(); fn vm_execution_unit_fn() -> Result<()> { let context = Context::with_default_modules()?; - let function: Function = run( - &context, - r#" - fn test() { 42 } - pub fn main() { test } - "#, - ["main"], - (), - )?; + let function: Function = run(&context, "fn test() { 42 } test", (), true)?; - let output: i64 = run( - &context, - r#" - pub fn main(f) { f() } - "#, - ["main"], - (function,), - )?; + let output: i64 = run(&context, "pub fn main(f) { f() }", (function,), false)?; assert_eq!(42, output); Ok(()) @@ -46,10 +31,10 @@ fn vm_execution_with_complex_external() -> Result<()> { r#" fn unit() { 84 } fn function() { (external, unit) } - pub fn main() { function } + function "#, - ["main"], (), + true, )?; let (o1, o2): (i64, i64) = run( @@ -60,8 +45,8 @@ fn vm_execution_with_complex_external() -> Result<()> { (f1(), f2()) } "#, - ["main"], (function,), + false, )?; assert_eq!(o1, 42); @@ -81,10 +66,10 @@ fn test_external_generator() -> Result<()> { &context, r#" fn test() { yield 42; } - pub fn main() { test } + test "#, - ["main"], (), + true, )?; let output: (Option, Option) = run( @@ -92,8 +77,8 @@ fn test_external_generator() -> Result<()> { r#" pub fn main(f) { let gen = f(); (gen.next(), gen.next()) } "#, - ["main"], (function,), + false, )?; assert_eq!((Some(42), None), output); diff --git a/crates/rune/src/tests/vm_general.rs b/crates/rune/src/tests/vm_general.rs index 320004b26..1ac9db9b9 100644 --- a/crates/rune/src/tests/vm_general.rs +++ b/crates/rune/src/tests/vm_general.rs @@ -6,11 +6,9 @@ prelude!(); fn test_template_string() { let out: String = eval( r#" - pub fn main() { - let name = "John Doe"; - `Hello ${name}, I am ${1 - 10} years old!` - } - "#, + let name = "John Doe"; + `Hello ${name}, I am ${1 - 10} years old!` + "#, ); assert_eq!(out, "Hello John Doe, I am -9 years old!"); @@ -19,16 +17,14 @@ fn test_template_string() { // accidentally clobber the scope. let out: String = eval( r#" - pub fn main() { - let name = "John Doe"; + let name = "John Doe"; - `Hello ${name}, I am ${{ - let a = 20; - a += 2; - a - }} years old!` - } - "#, + `Hello ${name}, I am ${{ + let a = 20; + a += 2; + a + }} years old!` + "#, ); assert_eq!(out, "Hello John Doe, I am 22 years old!"); } @@ -41,9 +37,7 @@ fn test_complex_field_access() { #{hello: #{world: 42}} } - pub fn main() { - Some((foo()).hello["world"]) - } + Some((foo()).hello["world"]) "#, ); assert_eq!(out, Some(42)); diff --git a/crates/rune/src/tests/vm_literals.rs b/crates/rune/src/tests/vm_literals.rs index 02a717a45..f8f1177bd 100644 --- a/crates/rune/src/tests/vm_literals.rs +++ b/crates/rune/src/tests/vm_literals.rs @@ -4,78 +4,41 @@ prelude!(); #[test] fn test_literals() { - let out: String = rune!( - pub fn main() { - "Hello World" - } - ); + let out: String = rune!("Hello World"); assert_eq!(out, "Hello World"); - - let out: Bytes = rune!( - pub fn main() { - b"Hello World" - } - ); + let out: Bytes = rune!(b"Hello World"); assert_eq!(out, b"Hello World"[..]); - - let out: u8 = rune!( - pub fn main() { - b'0' - } - ); + let out: u8 = rune!(b'0'); assert_eq!(out, b'0'); - let out: u8 = rune!( - pub fn main() { - b'\xaf' - } - ); + let out: u8 = rune!(b'\xaf'); assert_eq!(out, b'\xaf'); - - let out: char = rune!( - pub fn main() { - '\x60' - } - ); + let out: char = rune!('\x60'); assert_eq!(out, '\x60'); - let out: char = rune!( - pub fn main() { - '\u{1F4AF}' - } - ); + let out: char = rune!('\u{1F4AF}'); assert_eq!(out, '\u{1F4AF}'); - let out: char = rune!( - pub fn main() { - '💯' - } - ); + let out: char = rune!('💯'); assert_eq!(out, '💯'); } #[test] fn test_string_literals() { let out: String = rune!( - pub fn main() { - " + " " - } ); assert_eq!(out, "\n "); let out: String = rune!( - pub fn main() { - "\ + "\ " - } ); assert_eq!(out, ""); let out: String = rune!( - pub fn main() { - "\ + "\ a \ \ b" - } ); assert_eq!(out, "a b"); } @@ -83,28 +46,22 @@ fn test_string_literals() { #[test] fn test_byte_string_literals() { let out: Bytes = rune!( - pub fn main() { - b" + b" " - } ); assert_eq!(out, b"\n "[..]); let out: Bytes = rune!( - pub fn main() { - b"\ + b"\ " - } ); assert_eq!(out, b""[..]); let out: Bytes = rune!( - pub fn main() { - b"\ + b"\ a \ \ b" - } ); assert_eq!(out, b"a b"[..]); } @@ -117,11 +74,7 @@ fn test_number_literals() { }; ($lit:expr, $ty:ty) => { - let out: $ty = rune!( - pub fn main() { - $lit - } - ); + let out: $ty = rune!($lit); assert_eq!(out, $lit); }; } diff --git a/crates/rune/src/tests/vm_not_used.rs b/crates/rune/src/tests/vm_not_used.rs index eca51f5e0..3f5abc90e 100644 --- a/crates/rune/src/tests/vm_not_used.rs +++ b/crates/rune/src/tests/vm_not_used.rs @@ -3,16 +3,14 @@ prelude!(); #[test] fn test_not_used() { let _: () = rune! { - pub fn main() { - 0; - 4.1; - 'a'; - b'a'; - "Hello World"; - b"Hello World"; - [1, 2, 3]; - (1, 2, 3, 4); - #{"foo": 42, "bar": [1, 2, 3, 4]}; - } + 0; + 4.1; + 'a'; + b'a'; + "Hello World"; + b"Hello World"; + [1, 2, 3]; + (1, 2, 3, 4); + #{"foo": 42, "bar": [1, 2, 3, 4]}; }; } diff --git a/crates/rune/src/tests/vm_result.rs b/crates/rune/src/tests/vm_result.rs index e5e497168..e54a391b8 100644 --- a/crates/rune/src/tests/vm_result.rs +++ b/crates/rune/src/tests/vm_result.rs @@ -2,18 +2,21 @@ prelude!(); #[test] fn test_result() { - let out: i64 = rune! { - pub fn main() { match Err("err") { Err("err") => 1, _ => 2 } } - }; + let out: i64 = rune!(match Err("err") { + Err("err") => 1, + _ => 2, + }); assert_eq!(out, 1); - let out: i64 = rune! { - pub fn main() { match Err("err") { Ok("ok") => 1, _ => 2 } } - }; + let out: i64 = rune!(match Err("err") { + Ok("ok") => 1, + _ => 2, + }); assert_eq!(out, 2); - let out: i64 = rune! { - pub fn main() { match Ok("ok") { Ok("ok") => 1, _ => 2 } } - }; + let out: i64 = rune!(match Ok("ok") { + Ok("ok") => 1, + _ => 2, + }); assert_eq!(out, 1); } diff --git a/crates/rune/src/tests/vm_test_from_value_derive.rs b/crates/rune/src/tests/vm_test_from_value_derive.rs index 37db8eefb..c2f140bd3 100644 --- a/crates/rune/src/tests/vm_test_from_value_derive.rs +++ b/crates/rune/src/tests/vm_test_from_value_derive.rs @@ -12,14 +12,14 @@ fn test_from_value_object_like() { let value: Proxy = rune! { struct Ignored; struct Value { field, ignored } - pub fn main() { Value { field: 42, ignored: Ignored } } + Value { field: 42, ignored: Ignored } }; assert_eq!(value.field, 42); let value: Proxy = rune! { struct Ignored; - pub fn main() { #{ field: 42, ignored: Ignored } } + #{ field: 42, ignored: Ignored } }; assert_eq!(value.field, 42); @@ -32,15 +32,12 @@ fn test_from_value_tuple_like() { let value: Proxy = rune! { struct Value(field); - pub fn main() { Value(42) } + Value(42) }; assert_eq!(value.0, 42); - let value: Proxy = rune! { - pub fn main() { (42,) } - }; - + let value: Proxy = rune!((42,)); assert_eq!(value.0, 42); } @@ -54,11 +51,9 @@ fn test_missing_dynamic_field() { assert_vm_error!( ProxyStruct => r#" - pub fn main() { - struct Ignored; - struct Value { other, ignored } - Value { other: 42, ignored: Ignored } - } + struct Ignored; + struct Value { other, ignored } + Value { other: 42, ignored: Ignored } "#, MissingStructField { target, name } => { assert!(target.ends_with("::test_missing_dynamic_field::ProxyStruct")); @@ -72,11 +67,9 @@ fn test_missing_dynamic_field() { assert_vm_error!( ProxyTuple => r#" - pub fn main() { - struct Ignored; - struct Value(other); - Value(42) - } + struct Ignored; + struct Value(other); + Value(42) "#, MissingTupleIndex { target, index } => { assert!(target.ends_with("::test_missing_dynamic_field::ProxyTuple")); @@ -95,28 +88,22 @@ fn test_enum_proxy() { } let proxy: Proxy = rune! { - pub fn main() { - enum Proxy { Empty, Tuple(a), Struct { field } } - Proxy::Empty - } + enum Proxy { Empty, Tuple(a), Struct { field } } + Proxy::Empty }; assert_eq!(proxy, Proxy::Empty); let proxy: Proxy = rune! { - pub fn main() { - enum Proxy { Empty, Tuple(a), Struct { field } } - Proxy::Tuple("Hello World") - } + enum Proxy { Empty, Tuple(a), Struct { field } } + Proxy::Tuple("Hello World") }; assert_eq!(proxy, Proxy::Tuple(String::from("Hello World"))); let proxy: Proxy = rune! { - pub fn main() { - enum Proxy { Empty, Tuple(a), Struct { field } } - Proxy::Struct { field: "Hello World" } - } + enum Proxy { Empty, Tuple(a), Struct { field } } + Proxy::Struct { field: "Hello World" } }; assert_eq!( diff --git a/crates/rune/src/tests/vm_test_imports.rs b/crates/rune/src/tests/vm_test_imports.rs index 5bcb4b986..666dd61cc 100644 --- a/crates/rune/src/tests/vm_test_imports.rs +++ b/crates/rune/src/tests/vm_test_imports.rs @@ -17,9 +17,7 @@ fn test_grouped_imports() { } } - pub fn main() { - (c::VALUE, Foo::Bar is a::b::Foo, Baz is a::b::Foo) - } + (c::VALUE, Foo::Bar is a::b::Foo, Baz is a::b::Foo) }; assert_eq!(out, (2, true, true)); } @@ -28,20 +26,23 @@ fn test_grouped_imports() { fn test_reexport() { let out: i64 = rune! { mod inner { pub fn func() { 42 } } - pub use self::inner::func as main; + use self::inner::func as main; + main() }; assert_eq!(out, 42); let out: i64 = rune! { mod inner { pub fn func() { 42 } } - pub use crate::inner::func as main; + use crate::inner::func as main; + main() }; assert_eq!(out, 42); let out: i64 = rune! { mod inner2 { pub fn func() { 42 } } mod inner1 { pub use super::inner2::func; } - pub use crate::inner1::func as main; + use crate::inner1::func as main; + main() }; assert_eq!(out, 42); diff --git a/crates/rune/src/tests/vm_test_instance_fns.rs b/crates/rune/src/tests/vm_test_instance_fns.rs index fa6dc9c03..9a3de12c3 100644 --- a/crates/rune/src/tests/vm_test_instance_fns.rs +++ b/crates/rune/src/tests/vm_test_instance_fns.rs @@ -31,9 +31,7 @@ fn test_instance_kinds() { } } - pub fn main() { - (Foo { n: 3 }.test(1), Custom::A(4).test(), Custom::B{n: 5}.test(), Custom::C.test()) - } + (Foo { n: 3 }.test(1), Custom::A(4).test(), Custom::B{n: 5}.test(), Custom::C.test()) }; assert_eq!(out, (4, 5, 6, 7)); diff --git a/crates/rune/src/tests/vm_test_linked_list.rs b/crates/rune/src/tests/vm_test_linked_list.rs index 85a576bdc..8d6a7178a 100644 --- a/crates/rune/src/tests/vm_test_linked_list.rs +++ b/crates/rune/src/tests/vm_test_linked_list.rs @@ -68,22 +68,20 @@ fn test_linked_list() { } } - pub fn main() { - let ll = List::new(); - ll.push_back(1); - ll.push_back(2); - ll.push_back(3); + let ll = List::new(); + ll.push_back(1); + ll.push_back(2); + ll.push_back(3); - let it = ll.iter(); + let it = ll.iter(); - let out = []; + let out = []; - while let Some(value) = Iter::next(it) { - out.push(value); - } - - out + while let Some(value) = Iter::next(it) { + out.push(value); } + + out }; assert_eq!(out, vec![1, 2, 3]); diff --git a/crates/rune/src/tests/vm_test_mod.rs b/crates/rune/src/tests/vm_test_mod.rs index c090a9204..8db416f88 100644 --- a/crates/rune/src/tests/vm_test_mod.rs +++ b/crates/rune/src/tests/vm_test_mod.rs @@ -15,9 +15,7 @@ fn test_nested_mods() { } } - pub fn main() { - hello::test() - } + hello::test() }; assert_eq!(out, 3); } diff --git a/crates/rune/src/tests/vm_try.rs b/crates/rune/src/tests/vm_try.rs index 477176b0c..16b039d17 100644 --- a/crates/rune/src/tests/vm_try.rs +++ b/crates/rune/src/tests/vm_try.rs @@ -19,23 +19,20 @@ fn custom_try() -> Result<()> { } })?; - assert_eq!( - 42, - rune_n! { - &module, - (CustomResult(true),), - i64 => pub fn main(r) { r? } - } - ); - - assert_eq!( - Err(0), - rune_n! { - &module, - (CustomResult(false),), - Result<(), i64> => pub fn main(r) { r? } - } - ); + let n: u32 = rune_n! { + mod module, + (CustomResult(true),), + pub fn main(r) { r? } + }; + + assert_eq!(n, 42); + + let result: Result<(), i64> = rune_n! { + mod module, + (CustomResult(false),), + pub fn main(r) { r? } + }; + assert_eq!(result, Err(0)); Ok(()) } diff --git a/crates/rune/src/tests/wildcard_imports.rs b/crates/rune/src/tests/wildcard_imports.rs index 95c242d0c..87e7c9816 100644 --- a/crates/rune/src/tests/wildcard_imports.rs +++ b/crates/rune/src/tests/wildcard_imports.rs @@ -7,7 +7,7 @@ fn test_wildcard_precedence() { mod b { pub struct Foo; } use {a::*, b::*}; use b::Foo; - pub fn main() { Foo is b::Foo } + Foo is b::Foo }; rune_assert! { @@ -15,7 +15,7 @@ fn test_wildcard_precedence() { mod b { pub struct Foo; } use {b::*, a::*}; use a::Foo; - pub fn main() { Foo is a::Foo } + Foo is a::Foo }; rune_assert! { @@ -24,7 +24,7 @@ fn test_wildcard_precedence() { use a::*; use b::*; use a::Foo; - pub fn main() { Foo is a::Foo } + Foo is a::Foo }; rune_assert! { @@ -33,6 +33,6 @@ fn test_wildcard_precedence() { use a::Foo; use a::*; use b::*; - pub fn main() { Foo is a::Foo } + Foo is a::Foo }; }