2661 - warn if a reply doesn't match recipe header
Thanks Nicolas Léveillé for running up against this bug: https://news.ycombinator.com/item?id=11094837 (Also noticed and fixed several subsidiary issues. This whole aspect doesn't seem fully baked yet.)
This commit is contained in:
parent
f592d8629f
commit
4637d58f6c
|
@ -105,8 +105,9 @@ void check_types_of_reply_instructions(recipe_ordinal r) {
|
|||
raise_error << maybe(caller.name) << "too few ingredients in '" << caller_instruction.to_string() << "'\n" << end();
|
||||
goto finish_reply_check;
|
||||
}
|
||||
if (!is_dummy(caller_instruction.products.at(i)) && caller_instruction.products.at(i).name != caller_instruction.ingredients.at(ingredient_index).name)
|
||||
if (!is_dummy(caller_instruction.products.at(i)) && !is_literal(caller_instruction.ingredients.at(ingredient_index)) && caller_instruction.products.at(i).name != caller_instruction.ingredients.at(ingredient_index).name) {
|
||||
raise_error << maybe(caller.name) << "'" << caller_instruction.to_string() << "' should write to " << caller_instruction.ingredients.at(ingredient_index).original_string << " rather than " << caller_instruction.products.at(i).original_string << '\n' << end();
|
||||
}
|
||||
}
|
||||
}
|
||||
finish_reply_check:;
|
||||
|
|
|
@ -286,19 +286,32 @@ Transform.push_back(check_reply_instructions_against_header); // idempotent
|
|||
:(code)
|
||||
void check_reply_instructions_against_header(const recipe_ordinal r) {
|
||||
const recipe& caller_recipe = get(Recipe, r);
|
||||
if (caller_recipe.products.empty()) return;
|
||||
if (!caller_recipe.has_header) return;
|
||||
trace(9991, "transform") << "--- checking reply instructions against header for " << caller_recipe.name << end();
|
||||
//? cerr << "--- checking reply instructions against header for " << caller_recipe.name << '\n';
|
||||
for (long long int i = 0; i < SIZE(caller_recipe.steps); ++i) {
|
||||
const instruction& inst = caller_recipe.steps.at(i);
|
||||
if (inst.name != "reply") continue;
|
||||
for (long long int i = 0; i < min(SIZE(caller_recipe.products), SIZE(inst.ingredients)); ++i) {
|
||||
if (SIZE(caller_recipe.products) != SIZE(inst.ingredients)) {
|
||||
raise_error << maybe(caller_recipe.name) << "replied with the wrong number of products at '" << inst.to_string() << "'\n" << end();
|
||||
continue;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(caller_recipe.products); ++i) {
|
||||
if (!types_match(caller_recipe.products.at(i), inst.ingredients.at(i)))
|
||||
raise_error << maybe(caller_recipe.name) << "replied with the wrong type at '" << inst.to_string() << "'\n" << end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:(scenario recipe_headers_are_checked_2)
|
||||
% Hide_errors = true;
|
||||
recipe add2 x:number, y:number [
|
||||
local-scope
|
||||
load-ingredients
|
||||
z:address:number <- copy 0/unsafe
|
||||
reply z
|
||||
]
|
||||
+error: add2: replied with the wrong number of products at 'reply z'
|
||||
|
||||
:(scenario recipe_headers_check_for_duplicate_names)
|
||||
% Hide_errors = true;
|
||||
recipe add2 x:number, x:number -> z:number [
|
||||
|
@ -415,7 +428,7 @@ void fill_in_reply_ingredients(recipe_ordinal r) {
|
|||
trace(9991, "transform") << "--- fill in reply ingredients from header for recipe " << caller_recipe.name << end();
|
||||
for (long long int i = 0; i < SIZE(caller_recipe.steps); ++i) {
|
||||
instruction& inst = caller_recipe.steps.at(i);
|
||||
if (inst.name == "reply" && inst.ingredients.empty())
|
||||
if (inst.name == "reply")
|
||||
add_header_products(inst, caller_recipe);
|
||||
}
|
||||
// fall through reply
|
||||
|
|
|
@ -2310,9 +2310,10 @@ after <scroll-up> [
|
|||
# takes a pointer into the doubly-linked list, scans back to before start of
|
||||
# previous *wrapped* line
|
||||
# beware: never return null pointer
|
||||
recipe before-previous-line curr:address:shared:duplex-list:character, editor:address:shared:editor-data -> curr:address:shared:duplex-list:character [
|
||||
recipe before-previous-line in:address:shared:duplex-list:character, editor:address:shared:editor-data -> out:address:shared:duplex-list:character [
|
||||
local-scope
|
||||
load-ingredients
|
||||
curr:address:shared:duplex-list:character <- copy in
|
||||
c:character <- get *curr, value:offset
|
||||
# compute max, number of characters to skip
|
||||
# 1 + len%(width-1)
|
||||
|
|
|
@ -2310,9 +2310,10 @@ after <scroll-up> [
|
|||
# takes a pointer into the doubly-linked list, scans back to before start of
|
||||
# previous *wrapped* line
|
||||
# beware: never return null pointer
|
||||
recipe before-previous-line curr:address:shared:duplex-list:character, editor:address:shared:editor-data -> curr:address:shared:duplex-list:character [
|
||||
recipe before-previous-line in:address:shared:duplex-list:character, editor:address:shared:editor-data -> out:address:shared:duplex-list:character [
|
||||
local-scope
|
||||
load-ingredients
|
||||
curr:address:shared:duplex-list:character <- copy in
|
||||
c:character <- get *curr, value:offset
|
||||
# compute max, number of characters to skip
|
||||
# 1 + len%(width-1)
|
||||
|
|
Loading…
Reference in New Issue