diff --git a/crates/mun_memory/src/mapping.rs b/crates/mun_memory/src/mapping.rs index 4f5ec94b..2cfcb6f2 100644 --- a/crates/mun_memory/src/mapping.rs +++ b/crates/mun_memory/src/mapping.rs @@ -9,6 +9,7 @@ use crate::{ use std::collections::{HashMap, HashSet}; /// The type mapping needed to convert an old into a new set of unique and ordered values. +#[derive(Debug)] pub struct Mapping { /// The types that were deleted pub deletions: HashSet, @@ -19,6 +20,7 @@ pub struct Mapping { } /// The struct mapping needed to convert an old into a new struct of unique and ordered fields. +#[derive(Debug)] pub struct StructMapping { /// The field mappings for each original struct field pub field_mapping: Vec, diff --git a/crates/mun_runtime/tests/hot_reloading.rs b/crates/mun_runtime/tests/hot_reloading.rs index 78376e98..f4dba6f4 100644 --- a/crates/mun_runtime/tests/hot_reloading.rs +++ b/crates/mun_runtime/tests/hot_reloading.rs @@ -1,10 +1,11 @@ #[macro_use] mod util; +use mun_runtime::StructRef; use mun_test::CompileAndRunTestDriver; #[test] -fn hotreloadable() { +fn reloadable_function_single_file() { let mut driver = CompileAndRunTestDriver::new( r" pub fn main() -> i32 { 5 } @@ -14,7 +15,7 @@ fn hotreloadable() { .expect("Failed to build test driver"); assert_invoke_eq!(i32, 5, driver, "main"); - driver.update( + driver.update_file( "mod.mun", r" pub fn main() -> i32 { 10 } @@ -24,7 +25,37 @@ fn hotreloadable() { } #[test] -fn hotreload_struct_decl() { +fn reloadable_function_multi_file() { + let mut driver = CompileAndRunTestDriver::from_fixture( + r#" + //- /mun.toml + [package] + name="foo" + version="0.0.0" + + //- /src/mod.mun + use package::foo::bar; + pub fn main() -> i32 { bar() } + + //- /src/foo.mun + pub fn bar() -> i32 { 5 } + "#, + |builder| builder, + ) + .expect("Failed to build test driver"); + assert_invoke_eq!(i32, 5, driver, "main"); + + driver.update_file( + "foo.mun", + r#" + pub fn bar() -> i32 { 10 } + "#, + ); + assert_invoke_eq!(i32, 10, driver, "main"); +} + +#[test] +fn reloadable_struct_decl_single_file() { let mut driver = CompileAndRunTestDriver::new( r#" pub struct(gc) Args { @@ -33,18 +64,28 @@ fn hotreload_struct_decl() { } struct(gc) Bar { - m: f64, + m: i32, } pub fn args() -> Args { - Args { n: 3, foo: Bar { m: 1.0 }, } + Args { n: 3, foo: Bar { m: 1 }, } } "#, |builder| builder, ) .expect("Failed to build test driver"); - driver.update( + let args: StructRef = driver + .runtime + .invoke("args", ()) + .expect("Failed to call function"); + + let foo: StructRef = args.get("foo").expect("Failed to get struct field"); + assert_eq!(foo.get::("m").expect("Failed to get struct field"), 1); + + let foo = foo.root(); + + driver.update_file( "mod.mun", r#" pub struct(gc) Args { @@ -53,7 +94,7 @@ fn hotreload_struct_decl() { } struct(gc) Bar { - m: i32, + m: i64, } pub fn args() -> Args { @@ -61,4 +102,71 @@ fn hotreload_struct_decl() { } "#, ); + + let foo = foo.as_ref(&driver.runtime); + assert_eq!(foo.get::("m").expect("Failed to get struct field"), 1); +} + +#[test] +fn reloadable_struct_decl_multi_file() { + let mut driver = CompileAndRunTestDriver::from_fixture( + r#" + //- /mun.toml + [package] + name="foo" + version="0.0.0" + + //- /src/mod.mun + use package::foo::Bar; + pub struct(gc) Args { + n: i32, + foo: Bar, + } + + pub fn args() -> Args { + Args { n: 3, foo: Bar { m: 1 }, } + } + + //- /src/foo.mun + struct(gc) Bar { + m: i64, + } + "#, + |builder| builder, + ) + .expect("Failed to build test driver"); + + let args: StructRef = driver + .runtime + .invoke("args", ()) + .expect("Failed to call function"); + + assert_eq!(args.get::("n").expect("Failed to get struct field"), 3); + + let foo: StructRef = args.get("foo").expect("Failed to get struct field"); + assert_eq!(foo.get::("m").expect("Failed to get struct field"), 1); + + let args = args.root(); + let foo = foo.root(); + + driver.update_file( + "mod.mun", + r#" + use package::foo::Bar; + pub struct(gc) Args { + n: i64, + foo: Bar, + } + + pub fn args() -> Args { + Args { n: 3, foo: Bar { m: 1 }, } + } + "#, + ); + + let args = args.as_ref(&driver.runtime); + assert_eq!(args.get::("n").expect("Failed to get struct field"), 3); + + let foo = foo.as_ref(&driver.runtime); + assert_eq!(foo.get::("m").expect("Failed to get struct field"), 1); } diff --git a/crates/mun_runtime/tests/memory.rs b/crates/mun_runtime/tests/memory.rs index e8a4ab24..43d76a2f 100644 --- a/crates/mun_runtime/tests/memory.rs +++ b/crates/mun_runtime/tests/memory.rs @@ -65,7 +65,7 @@ fn map_struct_insert_field1() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -104,7 +104,7 @@ fn map_struct_insert_field2() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -150,7 +150,7 @@ fn map_struct_insert_field3() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -198,7 +198,7 @@ fn map_struct_remove_field1() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -236,7 +236,7 @@ fn map_struct_remove_field2() { let result: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let rooted_result = result.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -277,7 +277,7 @@ fn map_struct_remove_field3() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -319,7 +319,7 @@ fn map_struct_cast_fields1() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c, d, e)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo( @@ -373,7 +373,7 @@ fn map_struct_cast_fields2() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a,)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo( @@ -412,7 +412,7 @@ fn map_struct_swap_fields1() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -462,7 +462,7 @@ fn map_struct_swap_fields2() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -515,7 +515,7 @@ fn map_struct_rename_field1() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -563,7 +563,7 @@ fn map_struct_rename_field2() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -613,7 +613,7 @@ fn map_struct_all() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -667,7 +667,7 @@ fn map_array_to_array_different_array_to_primitive_different() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -726,7 +726,7 @@ fn map_array_to_array_different_array_to_primitive_same() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -794,7 +794,7 @@ fn map_array_to_array_different_array_to_struct_different() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct(gc) Bar(i64); @@ -868,7 +868,7 @@ fn map_array_to_array_different_array_to_struct_same() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Bar(i32); @@ -933,7 +933,7 @@ fn map_array_to_array_different_primitive_to_array_different() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -996,7 +996,7 @@ fn map_array_to_array_different_primitive_to_array_same() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -1056,7 +1056,7 @@ fn map_array_to_array_different_primitive_to_primitive() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -1116,7 +1116,7 @@ fn map_array_to_array_different_primitive_to_struct() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct(gc) Bar(i64); @@ -1187,7 +1187,7 @@ fn map_array_to_array_different_struct_to_array_different() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Bar(i64); @@ -1270,7 +1270,7 @@ fn map_array_to_array_different_struct_to_array_same() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Bar(i32); @@ -1353,7 +1353,7 @@ fn map_array_to_array_different_struct_to_struct() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct(gc) Bar(i64); @@ -1420,7 +1420,7 @@ fn map_array_to_array_same_primitive() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -1475,7 +1475,7 @@ fn map_array_to_array_same_struct() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Bar(f64); @@ -1538,7 +1538,7 @@ fn map_array_to_primitive_different() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -1588,7 +1588,7 @@ fn map_array_to_primitive_same() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -1643,7 +1643,7 @@ fn map_array_to_struct_different() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct(gc) Bar(f64); @@ -1711,7 +1711,7 @@ fn map_array_to_struct_same() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct(gc) Bar(f32); @@ -1776,7 +1776,7 @@ fn map_primitive_to_array_same() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -1840,7 +1840,7 @@ fn map_primitive_to_array_different() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c, d)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Foo { @@ -1910,7 +1910,7 @@ fn map_struct_to_array_same() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Bar(f64); @@ -1975,7 +1975,7 @@ fn map_struct_to_array_different() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Bar(f64); @@ -2036,7 +2036,7 @@ fn insert_array() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Foo { @@ -2084,7 +2084,7 @@ fn delete_used_struct() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, b, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" pub struct Bar(i64); @@ -2163,7 +2163,7 @@ fn nested_structs() { let value_wrapper = value_wrapper.root(); // Tests mapping of `gc -> gc`, `value -> value` - driver.update( + driver.update_file( "mod.mun", r#" pub struct(gc) GcStruct(f64, f64); @@ -2203,7 +2203,7 @@ fn nested_structs() { assert_eq!(value_1.get::("1"), Ok(b.into())); // Tests an identity mapping - driver.update( + driver.update_file( "mod.mun", r#" pub struct(gc) GcStruct(f64, f64); @@ -2248,7 +2248,7 @@ fn nested_structs() { let value_1 = value_1.root(); // Tests mapping of `gc -> value`, `value -> gc` - driver.update( + driver.update_file( "mod.mun", r#" struct(value) GcStruct(f64, f64); @@ -2285,7 +2285,7 @@ fn nested_structs() { // Tests mapping of different struct type, when `gc -> value`, `value -> gc`, and // retention of an old library (due to removal of `GcStruct` and `ValueStruct`) - driver.update( + driver.update_file( "mod.mun", r#" struct(gc) GcStruct2(f64); @@ -2356,7 +2356,7 @@ fn nested_structs() { let value_1 = value_1.root(); // Tests mapping of different struct type, when `gc -> gc`, `value -> value` - driver.update( + driver.update_file( "mod.mun", r#" struct(gc) GcStruct(f64, f64); @@ -2431,7 +2431,7 @@ fn insert_struct() { let foo_struct: StructRef = driver.runtime.invoke("foo_new", (a, c)).unwrap(); let foo_struct = foo_struct.root(); - driver.update( + driver.update_file( "mod.mun", r#" struct Bar(i64); diff --git a/crates/mun_test/src/driver.rs b/crates/mun_test/src/driver.rs index 9e08073f..fa39ec8c 100644 --- a/crates/mun_test/src/driver.rs +++ b/crates/mun_test/src/driver.rs @@ -91,7 +91,7 @@ impl CompileTestDriver { /// Updates the text of the Mun source and ensures that the generated assembly has been /// recompiled. - pub fn update(&mut self, path: impl AsRef, text: &str) { + pub fn update_file(&mut self, path: impl AsRef, text: &str) { self.driver.set_file_text(path, text).unwrap(); let compiler_errors = self @@ -177,8 +177,8 @@ impl CompileAndRunTestDriver { /// A reference to the borrowed `runtime` is used as an argument to allow moving of the /// existing borrow inside the update function. This obviates the necessity for `update` to use /// the `Runtime`. - pub fn update(&mut self, path: impl AsRef, text: &str) { - self.driver.update(path, text); + pub fn update_file(&mut self, path: impl AsRef, text: &str) { + self.driver.update_file(path, text); let start_time = Instant::now();