about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-11-29 12:10:22 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-11-29 12:10:22 -0800
commit81c87f08fa4fd9a27908b1d92c8aa897ad20cbb8 (patch)
treeb083537d5a5d7ca4b12970ec287ba52ff1edfaa4
parent691b529e53a608c0837599f2562897e01fda1888 (diff)
downloadmu-81c87f08fa4fd9a27908b1d92c8aa897ad20cbb8.tar.gz
2608 - improve errors when static dispatch fails
-rw-r--r--035call_ingredient.cc4
-rw-r--r--036call_reply.cc1
-rw-r--r--057static_dispatch.cc50
3 files changed, 53 insertions, 2 deletions
diff --git a/035call_ingredient.cc b/035call_ingredient.cc
index b949230d..7036fa06 100644
--- a/035call_ingredient.cc
+++ b/035call_ingredient.cc
@@ -59,8 +59,8 @@ case NEXT_INGREDIENT: {
       if (!is_mu_string(product))
         raise_error << "main: wrong type for ingredient " << product.original_string << '\n' << end();
     }
-    else if (!types_match(product,
-                          current_call().ingredients.at(current_call().next_ingredient_to_process))) {
+    else if (!types_coercible(product,
+                              current_call().ingredients.at(current_call().next_ingredient_to_process))) {
       raise_error << maybe(current_recipe_name()) << "wrong type for ingredient " << product.original_string << '\n' << end();
       // End next-ingredient Type Mismatch Error
     }
diff --git a/036call_reply.cc b/036call_reply.cc
index 6b881e4f..fef2351d 100644
--- a/036call_reply.cc
+++ b/036call_reply.cc
@@ -47,6 +47,7 @@ case REPLY: {
       reagent rhs = caller_instruction.products.at(i);
       canonize_type(rhs);
       raise_error << debug_string(lhs.type) << " vs " << debug_string(rhs.type) << '\n' << end();
+      // End reply Type Mismatch Error
       goto finish_reply;
     }
   }
diff --git a/057static_dispatch.cc b/057static_dispatch.cc
index 6613012a..c7f155f1 100644
--- a/057static_dispatch.cc
+++ b/057static_dispatch.cc
@@ -343,3 +343,53 @@ recipe foo x:number -> y:number [
 ]
 # number variant is preferred
 +mem: storing 35 in location 1
+
+//: after we make all attempts to dispatch, any unhandled cases will end up at
+//: some wrong variant and trigger an error while trying to load-ingredients
+
+:(scenario static_dispatch_shows_clear_error_on_missing_variant)
+% Hide_errors = true;
+recipe main [
+  1:number <- foo 34
+]
+recipe foo x:boolean -> y:number [
+  local-scope
+  load-ingredients
+  reply 35
+]
++error: foo: wrong type for ingredient x:boolean
++error:   (we're inside recipe foo x:boolean -> y:number)
++error:   (we're trying to call 1:number <- foo 34)
+
+:(before "End next-ingredient Type Mismatch Error")
+raise_error << "   (we're inside " << header_label(current_call().running_recipe) << ")\n" << end();
+raise_error << "   (we're trying to call " << to_instruction(*++Current_routine->calls.begin()).to_string() << ")\n" << end();
+
+:(scenario static_dispatch_shows_clear_error_on_missing_variant_2)
+% Hide_errors = true;
+recipe main [
+  1:boolean <- foo 34
+]
+recipe foo x:number -> y:number [
+  local-scope
+  load-ingredients
+  reply x
+]
++error: foo: reply ingredient x can't be saved in 1:boolean
++error:   (we just returned from recipe foo x:number -> y:number)
+
+:(before "End reply Type Mismatch Error")
+raise_error << "   (we just returned from " << header_label(caller_instruction.operation) << ")\n" << end();
+
+:(code)
+string header_label(recipe_ordinal r) {
+  const recipe& caller = get(Recipe, r);
+  ostringstream out;
+  out << "recipe " << caller.name << ' ';
+  for (long long int i = 0; i < SIZE(caller.ingredients); ++i)
+    out << caller.ingredients.at(i).original_string << ' ';
+  if (!caller.products.empty()) out << "->";
+  for (long long int i = 0; i < SIZE(caller.products); ++i)
+    out << ' ' << caller.products.at(i).original_string;
+  return out.str();
+}