From f9051e31cc03356e8105c2c0802a11468f769446 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Thu, 30 Jul 2020 11:31:52 +0200 Subject: [PATCH] refactor: Catch more panics for better test reporting --- check/tests/pass.rs | 13 +++++++++++++ src/import.rs | 14 +++++++++----- tests/inline.rs | 11 ++++++++++- tests/main.rs | 32 +++++++++++++++++++++++++------- vm/src/core/mod.rs | 4 +--- 5 files changed, 58 insertions(+), 16 deletions(-) diff --git a/check/tests/pass.rs b/check/tests/pass.rs index f230cc4f5f..71db24e5a7 100644 --- a/check/tests/pass.rs +++ b/check/tests/pass.rs @@ -1135,3 +1135,16 @@ match writer with "#, "test.List String" } + +test_check! { + issue_863, + r#" +#[infix(right, 0)] +let (<|) f x : (a -> b) -> a -> b = f x + +let g f x = x +let f a = + g a <| f a +{ f } + "# +} diff --git a/src/import.rs b/src/import.rs index 722cf59f03..29801d975c 100644 --- a/src/import.rs +++ b/src/import.rs @@ -595,11 +595,15 @@ where Box::pin(async move { Ok(From::from(move || { async move { - let mut db = salsa::OwnedDb::::from(&mut db); - db.import(modulename) - .await - .map_err(|err| MacroError::message(err.to_string())) - .map(move |id| pos::spanned(span, Expr::Ident(id))) + let result = { + let mut db = salsa::OwnedDb::::from(&mut db); + db.import(modulename) + .await + .map_err(|err| MacroError::message(err.to_string())) + .map(move |id| pos::spanned(span, Expr::Ident(id))) + }; + drop(db); + result } .boxed() })) diff --git a/tests/inline.rs b/tests/inline.rs index d6409de12a..54af4d01cb 100644 --- a/tests/inline.rs +++ b/tests/inline.rs @@ -3,7 +3,7 @@ use support::*; mod support; -use gluon::{self, query::Compilation, vm::core::tests::check_expr_eq, ThreadExt}; +use gluon::{self, query::{Compilation, AsyncCompilation}, vm::core::tests::check_expr_eq, ThreadExt}; #[tokio::test] async fn inline_cross_module() { @@ -24,6 +24,7 @@ async fn inline_cross_module() { .unwrap_or_else(|err| panic!("{}", err)); let mut db = thread.get_database(); + let mut db = salsa::OwnedDb::::from(&mut db); let core_expr = db .core_expr("test".into(), None) .await @@ -69,6 +70,7 @@ num.(+) 3 .unwrap_or_else(|err| panic!("{}", err)); let mut db = thread.get_database(); + let mut db = salsa::OwnedDb::::from(&mut db); let core_expr = db .core_expr("test".into(), None) .await @@ -98,6 +100,7 @@ async fn inline_across_two_modules() { .unwrap_or_else(|err| panic!("{}", err)); let mut db = thread.get_database(); + let mut db = salsa::OwnedDb::::from(&mut db); let core_expr = db .core_expr("test".into(), None) .await @@ -127,6 +130,7 @@ async fn prune_prelude() { .unwrap_or_else(|err| panic!("{}", err)); let mut db = thread.get_database(); + let mut db = salsa::OwnedDb::::from(&mut db); let core_expr = db .core_expr("test".into(), None) .await @@ -161,6 +165,7 @@ async fn prune_factorial() { .unwrap_or_else(|err| panic!("{}", err)); let mut db = thread.get_database(); + let mut db = salsa::OwnedDb::::from(&mut db); let core_expr = db .core_expr("test".into(), None) .await @@ -198,6 +203,7 @@ mod.(+) (no_inline 1) 2 .unwrap_or_else(|err| panic!("{}", err)); let mut db = thread.get_database(); + let mut db = salsa::OwnedDb::::from(&mut db); let core_expr = db .core_expr("test".into(), None) .await @@ -236,6 +242,7 @@ match A with .unwrap_or_else(|err| panic!("{}", err)); let mut db = thread.get_database(); + let mut db = salsa::OwnedDb::::from(&mut db); let core_expr = db .core_expr("test".into(), None) .await @@ -267,6 +274,7 @@ m.(<) .unwrap_or_else(|err| panic!("{}", err)); let mut db = thread.get_database(); + let mut db = salsa::OwnedDb::::from(&mut db); let core_expr = db .core_expr("test".into(), None) .await @@ -300,6 +308,7 @@ f (Some 1) .unwrap_or_else(|err| panic!("{}", err)); let mut db = thread.get_database(); + let mut db = salsa::OwnedDb::::from(&mut db); let core_expr = db .core_expr("test".into(), None) .await diff --git a/tests/main.rs b/tests/main.rs index 90bb4838b6..41f9a28b13 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -182,9 +182,27 @@ impl TestCase { } } +async fn catch_unwind_test( + name: String, + f: impl Future>, +) -> tensile::Test { + std::panic::AssertUnwindSafe(f) + .catch_unwind() + .await + .unwrap_or_else(|err| { + let err = Error::from( + err.downcast::() + .map(|s| *s) + .or_else(|e| e.downcast::<&str>().map(|s| String::from(&s[..]))) + .unwrap_or_else(|_| "Unknown panic".to_string()), + ); + tensile::test(name, Err(err)) + }) +} + async fn make_test<'t>(vm: &'t Thread, name: &str, filename: &Path) -> Result { let text = fs::read_to_string(filename).await?; - let (De(test), _) = vm.run_expr_async(&name, &text).await?; + let (De(test), _) = std::panic::AssertUnwindSafe(vm.run_expr_async(&name, &text)).await?; Ok(test) } @@ -306,7 +324,7 @@ async fn run_doc_tests<'t>( .into_iter() .map(move |(test_name, test_source)| { let mut convert_test_fn = convert_test_fn.clone(); - async move { + catch_unwind_test(test_name.clone(), async move { let vm = vm.new_thread().unwrap(); match vm @@ -320,7 +338,7 @@ async fn run_doc_tests<'t>( tensile::test(test_name, || Err(err.0.into())) } } - } + }) }) .collect::>() .collect() @@ -366,7 +384,7 @@ async fn main_(options: &Opt) -> Result<(), Error> { let vm = vm.new_thread().unwrap(); let name2 = name.clone(); - pool.spawn_with_handle(async move { + pool.spawn_with_handle(catch_unwind_test(name.clone(), async move { match make_test(&vm, &name, &filename).await { Ok(test) => test.into_tensile_test(), Err(err) => { @@ -374,7 +392,7 @@ async fn main_(options: &Opt) -> Result<(), Error> { tensile::test(name2, || Err(err.0)) } } - }) + })) .expect("Could not spawn test future") }) .collect::>() @@ -404,7 +422,7 @@ async fn main_(options: &Opt) -> Result<(), Error> { .filter_map(&filter_fn) .map(|(filename, name)| { let vm = vm.new_thread().unwrap(); - pool.spawn_with_handle(async move { + pool.spawn_with_handle(catch_unwind_test(name.clone(), async move { match run_doc_tests(&vm, &name, &filename).await { Ok(tests) => tensile::group(name.clone(), tests), Err(err) => { @@ -412,7 +430,7 @@ async fn main_(options: &Opt) -> Result<(), Error> { tensile::test(name.clone(), || Err(err.0)) } } - }) + })) .expect("Could not spawn test future") }) .collect::>() diff --git a/vm/src/core/mod.rs b/vm/src/core/mod.rs index 0e22a40911..e708625ca5 100644 --- a/vm/src/core/mod.rs +++ b/vm/src/core/mod.rs @@ -1544,9 +1544,7 @@ fn get_return_type( .remove_forall() .as_function() .map(|t| Cow::Borrowed(t.1)) - .unwrap_or_else(|| { - panic!("Unexpected type {} is not a function", function_type); - }); + .ok_or_else(|| format!("Unexpected type {} is not a function", function_type))?; get_return_type(env, &ret, arg_count - 1) }