about summary refs log tree commit diff stats
path: root/054static_dispatch.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2017-04-20 10:09:14 -0700
committerKartik K. Agaram <vc@akkartik.com>2017-04-20 10:09:14 -0700
commitb7df1a7aabd5d4b57629c484daf060bfea2aaef3 (patch)
treef683c0b66c4e829cca29f7a6d2ab4dcf0035565c /054static_dispatch.cc
parentc43164727bfbe192763292e23dad983fbf09d18e (diff)
downloadmu-b7df1a7aabd5d4b57629c484daf060bfea2aaef3.tar.gz
3838 - further improve an error message
Expanded instructions don't seem to be worth the space they take up. Let
people think through the types of variables for themselves.

Thanks again to Ella Couch.
Diffstat (limited to '054static_dispatch.cc')
-rw-r--r--054static_dispatch.cc33
1 files changed, 19 insertions, 14 deletions
diff --git a/054static_dispatch.cc b/054static_dispatch.cc
index fe072d56..1ca6b2ca 100644
--- a/054static_dispatch.cc
+++ b/054static_dispatch.cc
@@ -195,18 +195,14 @@ string best_variant(instruction& inst, const recipe& caller_recipe) {
   // error messages
   if (get(Recipe_ordinal, inst.name) >= MAX_PRIMITIVE_RECIPES) {  // we currently don't check types for primitive variants
     if (SIZE(variants) == 1) {
-      raise << maybe(caller_recipe.name) << "instruction '" << inst.original_string << "' does not match '" << header_label(get(Recipe, variants.at(0))) << "'\n" << end();
-      raise << "  instruction expands to '" << to_string(inst) << "'\n" << end();
+      raise << maybe(caller_recipe.name) << "types don't match in call for '" << inst.original_string << "'\n" << end();
+      raise << "  which tries to call '" << original_header_label(get(Recipe, variants.at(0))) << "'\n" << end();
     }
     else {
       raise << maybe(caller_recipe.name) << "failed to find a matching call for '" << inst.original_string << "'\n" << end();
-      raise << "  which expands to:\n" << end();
-      raise << "    " << to_string(inst) << '\n' << end();
       raise << "  available variants are:\n" << end();
-      for (int i = 0;  i < SIZE(variants);  ++i) {
-        const recipe& curr = get(Recipe, variants.at(i));
-        raise << "    " << header_label(curr) << '\n' << end();
-      }
+      for (int i = 0;  i < SIZE(variants);  ++i)
+        raise << "    " << original_header_label(get(Recipe, variants.at(i))) << '\n' << end();
     }
     for (list<call>::iterator p = /*skip*/++Resolve_stack.begin();  p != Resolve_stack.end();  ++p) {
       const recipe& specializer_recipe = get(Recipe, p->running_recipe);
@@ -578,6 +574,17 @@ string header_label(const recipe& caller) {
   return out.str();
 }
 
+string original_header_label(const recipe& caller) {
+  ostringstream out;
+  out << "recipe " << caller.original_name;
+  for (int i = 0;  i < SIZE(caller.ingredients);  ++i)
+    out << ' ' << caller.ingredients.at(i).original_string;
+  if (!caller.products.empty()) out << " ->";
+  for (int i = 0;  i < SIZE(caller.products);  ++i)
+    out << ' ' << caller.products.at(i).original_string;
+  return out.str();
+}
+
 :(scenario reload_variant_retains_other_variants)
 def main [
   1:num <- copy 34
@@ -645,8 +652,8 @@ def foo x:&:char [
   local-scope
   load-ingredients
 ]
-+error: main: instruction 'foo x' does not match 'recipe foo {x: ("address" "character")}'
-+error:   instruction expands to 'foo {x: ("address" "number")}'
++error: main: types don't match in call for 'foo x'
++error:   which tries to call 'recipe foo x:&:char'
 
 :(scenario show_available_variants_in_dispatch_errors)
 % Hide_errors = true;
@@ -664,11 +671,9 @@ def foo x:&:bool [
   load-ingredients
 ]
 +error: main: failed to find a matching call for 'foo x'
-+error:   which expands to:
-+error:     foo {x: ("address" "number")}
 +error:   available variants are:
-+error:     recipe foo {x: ("address" "character")}
-+error:     recipe foo_2 {x: ("address" "boolean")}
++error:     recipe foo x:&:char
++error:     recipe foo x:&:bool
 
 :(before "End Includes")
 using std::abs;