about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--021check_instruction.cc22
-rw-r--r--056recipe_header.cc4
2 files changed, 22 insertions, 4 deletions
diff --git a/021check_instruction.cc b/021check_instruction.cc
index 58fd395f..03f1cc61 100644
--- a/021check_instruction.cc
+++ b/021check_instruction.cc
@@ -81,11 +81,21 @@ recipe main [
 +mem: storing 12 in location 2
 $error: 0
 
+:(scenario write_boolean_to_number_allowed)
+% Hide_errors = true;
+recipe main [
+  1:boolean <- copy 1/true
+  2:number <- copy 1:boolean
+]
++mem: storing 1 in location 2
+$error: 0
+
 :(code)
 // types_match with some leniency
-bool types_coercible(const reagent& lhs, const reagent& rhs) {
-  if (types_match(lhs, rhs)) return true;
-  if (is_mu_address(rhs) && is_mu_number(lhs)) return true;
+bool types_coercible(const reagent& to, const reagent& from) {
+  if (types_match(to, from)) return true;
+  if (is_mu_address(from) && is_mu_number(to)) return true;
+  if (is_mu_boolean(from) && is_mu_number(to)) return true;
   // End types_coercible Special-cases
   return false;
 }
@@ -152,6 +162,12 @@ bool is_mu_address(reagent r) {
   return r.type->value == get(Type_ordinal, "address");
 }
 
+bool is_mu_boolean(reagent r) {
+  if (!r.type) return false;
+  if (is_literal(r)) return false;
+  return r.type->value == get(Type_ordinal, "boolean");
+}
+
 bool is_mu_number(reagent r) {
   if (!r.type) return false;
   if (is_literal(r)) {
diff --git a/056recipe_header.cc b/056recipe_header.cc
index 130f832e..de6793de 100644
--- a/056recipe_header.cc
+++ b/056recipe_header.cc
@@ -216,6 +216,7 @@ void check_calls_against_header(const recipe_ordinal r) {
     const recipe& callee = get(Recipe, inst.operation);
     if (!callee.has_header) continue;
     for (long int i = 0; i < min(SIZE(inst.ingredients), SIZE(callee.ingredients)); ++i) {
+      // ingredients coerced from call to callee
       if (!types_coercible(callee.ingredients.at(i), inst.ingredients.at(i)))
         raise_error << maybe(caller.name) << "ingredient " << i << " has the wrong type at '" << inst.to_string() << "'\n" << end();
       if (is_unique_address(inst.ingredients.at(i)))
@@ -223,7 +224,8 @@ void check_calls_against_header(const recipe_ordinal r) {
     }
     for (long int i = 0; i < min(SIZE(inst.products), SIZE(callee.products)); ++i) {
       if (is_dummy(inst.products.at(i))) continue;
-      if (!types_coercible(callee.products.at(i), inst.products.at(i)))
+      // products coerced from callee to call
+      if (!types_coercible(inst.products.at(i), callee.products.at(i)))
         raise_error << maybe(caller.name) << "product " << i << " has the wrong type at '" << inst.to_string() << "'\n" << end();
       if (is_unique_address(inst.products.at(i)))
         raise << maybe(caller.name) << "try to avoid getting non-shared addresses out of calls, like product " << i << " at '" << inst.to_string() << "'\n" << end();