about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--030container.cc10
-rw-r--r--057static_dispatch.cc43
2 files changed, 49 insertions, 4 deletions
diff --git a/030container.cc b/030container.cc
index b470e8ad..f37d7283 100644
--- a/030container.cc
+++ b/030container.cc
@@ -534,17 +534,19 @@ Transform.push_back(check_or_set_invalid_types);  // idempotent
 
 :(code)
 void check_or_set_invalid_types(const recipe_ordinal r) {
-  for (long long int index = 0; index < SIZE(get(Recipe, r).steps); ++index) {
-    const instruction& inst = get(Recipe, r).steps.at(index);
+  recipe& caller = get(Recipe, r);
+  for (long long int index = 0; index < SIZE(caller.steps); ++index) {
+    instruction& inst = caller.steps.at(index);
     for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
       check_or_set_invalid_types(inst.ingredients.at(i).type, inst.ingredients.at(i).properties.at(0).second,
-                                 maybe(get(Recipe, r).name), "'"+inst.to_string()+"'");
+                                 maybe(caller.name), "'"+inst.to_string()+"'");
     }
     for (long long int i = 0; i < SIZE(inst.products); ++i) {
       check_or_set_invalid_types(inst.products.at(i).type, inst.products.at(i).properties.at(0).second,
-                                 maybe(get(Recipe, r).name), "'"+inst.to_string()+"'");
+                                 maybe(caller.name), "'"+inst.to_string()+"'");
     }
   }
+  // End check_or_set_invalid_types
 }
 
 void check_or_set_invalid_types(type_tree* type, const string_tree* type_name, const string& block, const string& name) {
diff --git a/057static_dispatch.cc b/057static_dispatch.cc
index 2aae9153..60221453 100644
--- a/057static_dispatch.cc
+++ b/057static_dispatch.cc
@@ -120,6 +120,17 @@ recipe test a:number, b:number -> z:number [
 ]
 +mem: storing 2 in location 7
 
+//: support recipe headers in a previous transform to fill in missing types
+:(before "End check_or_set_invalid_types")
+for (long long int i = 0; i < SIZE(caller.ingredients); ++i) {
+  check_or_set_invalid_types(caller.ingredients.at(i).type, caller.ingredients.at(i).properties.at(0).second,
+                             maybe(caller.name), "recipe header ingredient");
+}
+for (long long int i = 0; i < SIZE(caller.products); ++i) {
+  check_or_set_invalid_types(caller.products.at(i).type, caller.products.at(i).properties.at(0).second,
+                             maybe(caller.name), "recipe header product");
+}
+
 //: after filling in all missing types (because we'll be introducing 'blank' types in this transform in a later layer, for shape-shifting recipes)
 :(after "End Type Modifying Transforms")
 Transform.push_back(resolve_ambiguous_calls);  // idempotent
@@ -288,6 +299,38 @@ recipe test a:number, b:number -> z:point [
 ]
 $error: 0
 
+:(scenario static_dispatch_works_with_compound_type_containing_container_defined_after_first_use)
+% Hide_errors = true;
+recipe main [
+  x:address:foo <- new foo:type
+  test x
+]
+container foo [
+  x:number
+]
+recipe test a:address:foo -> z:number [
+  local-scope
+  load-ingredients
+  z:number <- get *a, x:offset
+]
+$error: 0
+
+:(scenario static_dispatch_works_with_compound_type_containing_container_defined_after_second_use)
+% Hide_errors = true;
+recipe main [
+  x:address:foo <- new foo:type
+  test x
+]
+recipe test a:address:foo -> z:number [
+  local-scope
+  load-ingredients
+  z:number <- get *a, x:offset
+]
+container foo [
+  x:number
+]
+$error: 0
+
 :(scenario static_dispatch_prefers_literals_to_be_numbers_rather_than_addresses)
 recipe main [
   1:number <- foo 0