diff options
-rw-r--r-- | 021check_instruction.cc | 22 | ||||
-rw-r--r-- | 056recipe_header.cc | 4 |
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(); |