about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--030container.cc40
-rw-r--r--033exclusive_container.cc6
-rw-r--r--036refcount.cc74
-rw-r--r--055shape_shifting_container.cc42
4 files changed, 81 insertions, 81 deletions
diff --git a/030container.cc b/030container.cc
index 4519e347..52c3c1ae 100644
--- a/030container.cc
+++ b/030container.cc
@@ -184,24 +184,24 @@ void compute_container_sizes(const recipe_ordinal r) {
     instruction& inst = caller.steps.at(i);
     trace(9993, "transform") << "- compute container sizes for " << to_string(inst) << end();
     for (int i = 0;  i < SIZE(inst.ingredients);  ++i)
-      compute_container_sizes(inst.ingredients.at(i));
+      compute_container_sizes(inst.ingredients.at(i), " in '"+to_original_string(inst)+"'");
     for (int i = 0;  i < SIZE(inst.products);  ++i)
-      compute_container_sizes(inst.products.at(i));
+      compute_container_sizes(inst.products.at(i), " in '"+to_original_string(inst)+"'");
   }
 }
 
-void compute_container_sizes(reagent& r) {
+void compute_container_sizes(reagent& r, const string& location_for_error_messages) {
   expand_type_abbreviations(r.type);
   if (is_literal(r) || is_dummy(r)) return;
   reagent rcopy = r;
   // Compute Container Size(reagent rcopy)
   set<type_tree> pending_metadata;  // might actually be faster to just convert to string rather than compare type_tree directly; so far the difference is negligible
-  compute_container_sizes(rcopy.type, pending_metadata);
+  compute_container_sizes(rcopy.type, pending_metadata, location_for_error_messages);
   if (contains_key(Container_metadata, rcopy.type))
     r.metadata = get(Container_metadata, rcopy.type);
 }
 
-void compute_container_sizes(const type_tree* type, set<type_tree>& pending_metadata) {
+void compute_container_sizes(const type_tree* type, set<type_tree>& pending_metadata, const string& location_for_error_messages) {
   if (!type) return;
   trace(9993, "transform") << "compute container sizes for " << to_string(type) << end();
   if (contains_key(Container_metadata, type)) return;
@@ -210,14 +210,14 @@ void compute_container_sizes(const type_tree* type, set<type_tree>& pending_meta
   if (!type->atom) {
     assert(type->left->atom);
     if (type->left->name == "address") {
-      compute_container_sizes(type->right, pending_metadata);
+      compute_container_sizes(type->right, pending_metadata, location_for_error_messages);
     }
     else if (type->left->name == "array") {
       const type_tree* element_type = type->right;
       // hack: support both array:num:3 and array:address:num
       if (!element_type->atom && element_type->right && element_type->right->atom && is_integer(element_type->right->name))
         element_type = element_type->left;
-      compute_container_sizes(element_type, pending_metadata);
+      compute_container_sizes(element_type, pending_metadata, location_for_error_messages);
     }
     // End compute_container_sizes Non-atom Cases
     return;
@@ -226,12 +226,12 @@ void compute_container_sizes(const type_tree* type, set<type_tree>& pending_meta
   if (!contains_key(Type, type->value)) return;  // error raised elsewhere
   type_info& info = get(Type, type->value);
   if (info.kind == CONTAINER) {
-    compute_container_sizes(info, type, pending_metadata);
+    compute_container_sizes(info, type, pending_metadata, location_for_error_messages);
   }
   // End compute_container_sizes Atom Cases
 }
 
-void compute_container_sizes(const type_info& container_info, const type_tree* full_type, set<type_tree>& pending_metadata) {
+void compute_container_sizes(const type_info& container_info, const type_tree* full_type, set<type_tree>& pending_metadata, const string& location_for_error_messages) {
   assert(container_info.kind == CONTAINER);
   // size of a container is the sum of the sizes of its element
   // (So it can only contain arrays if they're static and include their
@@ -240,7 +240,7 @@ void compute_container_sizes(const type_info& container_info, const type_tree* f
   for (int i = 0;  i < SIZE(container_info.elements);  ++i) {
     reagent/*copy*/ element = container_info.elements.at(i);
     // Compute Container Size(element, full_type)
-    compute_container_sizes(element.type, pending_metadata);
+    compute_container_sizes(element.type, pending_metadata, location_for_error_messages);
     metadata.offset.push_back(metadata.size);  // save previous size as offset
     metadata.size += size_of(element.type);
   }
@@ -290,7 +290,7 @@ void test_container_sizes() {
   reagent r("x:point");
   CHECK(!contains_key(Container_metadata, r.type));
   // scan
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   // the reagent we scanned knows its size
   CHECK_EQ(r.metadata.size, 2);
   // the global table also knows its size
@@ -303,7 +303,7 @@ void test_container_sizes_through_aliases() {
   put(Type_abbreviations, "pt", new_type_tree("point"));
   reagent r("x:pt");
   // scan
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   // the reagent we scanned knows its size
   CHECK_EQ(r.metadata.size, 2);
   // the global table also knows its size
@@ -316,7 +316,7 @@ void test_container_sizes_nested() {
   reagent r("x:point-number");
   CHECK(!contains_key(Container_metadata, r.type));
   // scan
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   // the reagent we scanned knows its size
   CHECK_EQ(r.metadata.size, 3);
   // the global table also knows its size
@@ -331,7 +331,7 @@ void test_container_sizes_recursive() {
       "  y:address:foo\n"
       "]\n");
   reagent r("x:foo");
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   CHECK_EQ(r.metadata.size, 2);
 }
 
@@ -341,7 +341,7 @@ void test_container_sizes_from_address() {
   CHECK(!contains_key(Container_metadata, container.type));
   // scanning an address to the container precomputes the size of the container
   reagent r("x:address:point");
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   CHECK(contains_key(Container_metadata, container.type));
   CHECK_EQ(get(Container_metadata, container.type).size, 2);
 }
@@ -352,7 +352,7 @@ void test_container_sizes_from_array() {
   CHECK(!contains_key(Container_metadata, container.type));
   // scanning an array of the container precomputes the size of the container
   reagent r("x:array:point");
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   CHECK(contains_key(Container_metadata, container.type));
   CHECK_EQ(get(Container_metadata, container.type).size, 2);
 }
@@ -363,7 +363,7 @@ void test_container_sizes_from_address_to_array() {
   CHECK(!contains_key(Container_metadata, container.type));
   // scanning an address to an array of the container precomputes the size of the container
   reagent r("x:address:array:point");
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   CHECK(contains_key(Container_metadata, container.type));
   CHECK_EQ(get(Container_metadata, container.type).size, 2);
 }
@@ -374,7 +374,7 @@ void test_container_sizes_from_static_array() {
   int old_size = SIZE(Container_metadata);
   // scanning an address to an array of the container precomputes the size of the container
   reagent r("x:array:point:10");
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   CHECK(contains_key(Container_metadata, container.type));
   CHECK_EQ(get(Container_metadata, container.type).size, 2);
   // no non-container types precomputed
@@ -387,7 +387,7 @@ void test_container_sizes_from_address_to_static_array() {
   int old_size = SIZE(Container_metadata);
   // scanning an address to an array of the container precomputes the size of the container
   reagent r("x:address:array:point:10");
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   CHECK(contains_key(Container_metadata, container.type));
   CHECK_EQ(get(Container_metadata, container.type).size, 2);
   // no non-container types precomputed
@@ -400,7 +400,7 @@ void test_container_sizes_from_repeated_address_and_array_types() {
   int old_size = SIZE(Container_metadata);
   // scanning repeated address and array types modifying the container precomputes the size of the container
   reagent r("x:address:array:address:array:point:10");
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   CHECK(contains_key(Container_metadata, container.type));
   CHECK_EQ(get(Container_metadata, container.type).size, 2);
   // no non-container types precomputed
diff --git a/033exclusive_container.cc b/033exclusive_container.cc
index 800f1a86..88b33639 100644
--- a/033exclusive_container.cc
+++ b/033exclusive_container.cc
@@ -37,11 +37,11 @@ if (t.kind == EXCLUSIVE_CONTAINER) {
 }
 :(before "End compute_container_sizes Atom Cases")
 if (info.kind == EXCLUSIVE_CONTAINER) {
-  compute_exclusive_container_sizes(info, type, pending_metadata);
+  compute_exclusive_container_sizes(info, type, pending_metadata, location_for_error_messages);
 }
 
 :(code)
-void compute_exclusive_container_sizes(const type_info& exclusive_container_info, const type_tree* full_type, set<type_tree>& pending_metadata) {
+void compute_exclusive_container_sizes(const type_info& exclusive_container_info, const type_tree* full_type, set<type_tree>& pending_metadata, const string& location_for_error_messages) {
   // size of an exclusive container is the size of its largest variant
   // (So, like containers, it can only contain arrays if they're static and
   // include their length in the type.)
@@ -49,7 +49,7 @@ void compute_exclusive_container_sizes(const type_info& exclusive_container_info
   for (int i = 0;  i < SIZE(exclusive_container_info.elements);  ++i) {
     reagent/*copy*/ element = exclusive_container_info.elements.at(i);
     // Compute Exclusive Container Size(element, full_type)
-    compute_container_sizes(element.type, pending_metadata);
+    compute_container_sizes(element.type, pending_metadata, location_for_error_messages);
     int variant_size = size_of(element);
     if (variant_size > metadata.size) metadata.size = variant_size;
   }
diff --git a/036refcount.cc b/036refcount.cc
index 009defa1..267eb364 100644
--- a/036refcount.cc
+++ b/036refcount.cc
@@ -290,65 +290,65 @@ void compute_container_address_offsets(const recipe_ordinal r) {
     instruction& inst = caller.steps.at(i);
     trace(9993, "transform") << "- compute address offsets for " << to_string(inst) << end();
     for (int i = 0;  i < SIZE(inst.ingredients);  ++i)
-      compute_container_address_offsets(inst.ingredients.at(i));
+      compute_container_address_offsets(inst.ingredients.at(i), " in '"+to_original_string(inst)+"'");
     for (int i = 0;  i < SIZE(inst.products);  ++i)
-      compute_container_address_offsets(inst.products.at(i));
+      compute_container_address_offsets(inst.products.at(i), " in '"+to_original_string(inst)+"'");
   }
 }
 
-void compute_container_address_offsets(reagent& r) {
+void compute_container_address_offsets(reagent& r, const string& location_for_error_messages) {
   if (is_literal(r) || is_dummy(r)) return;
-  compute_container_address_offsets(r.type);
+  compute_container_address_offsets(r.type, location_for_error_messages);
   if (contains_key(Container_metadata, r.type))
     r.metadata = get(Container_metadata, r.type);
 }
 
 // the recursive structure of this function needs to exactly match
 // compute_container_sizes
-void compute_container_address_offsets(const type_tree* type) {
+void compute_container_address_offsets(const type_tree* type, const string& location_for_error_messages) {
   if (!type) return;
   if (!type->atom) {
     assert(type->left->atom);
     if (type->left->name == "address") {
-      compute_container_address_offsets(type->right);
+      compute_container_address_offsets(type->right, location_for_error_messages);
     }
     else if (type->left->name == "array") {
       const type_tree* element_type = type->right;
       // hack: support both array:num:3 and array:address:num
       if (!element_type->atom && element_type->right && element_type->right->atom && is_integer(element_type->right->name))
         element_type = element_type->left;
-      compute_container_address_offsets(element_type);
+      compute_container_address_offsets(element_type, location_for_error_messages);
     }
     // End compute_container_address_offsets Non-atom Cases
   }
   if (!contains_key(Type, root_type(type)->value)) return;  // error raised elsewhere
   type_info& info = get(Type, root_type(type)->value);
   if (info.kind == CONTAINER) {
-    compute_container_address_offsets(info, type);
+    compute_container_address_offsets(info, type, location_for_error_messages);
   }
   if (info.kind == EXCLUSIVE_CONTAINER) {
-    compute_exclusive_container_address_offsets(info, type);
+    compute_exclusive_container_address_offsets(info, type, location_for_error_messages);
   }
 }
 
-void compute_container_address_offsets(const type_info& container_info, const type_tree* full_type) {
+void compute_container_address_offsets(const type_info& container_info, const type_tree* full_type, const string& location_for_error_messages) {
   container_metadata& metadata = get(Container_metadata, full_type);
   if (!metadata.address.empty()) return;
   trace(9994, "transform") << "compute address offsets for container " << container_info.name << end();
-  append_addresses(0, full_type, metadata.address, set<tag_condition_info>());
+  append_addresses(0, full_type, metadata.address, set<tag_condition_info>(), location_for_error_messages);
 }
 
-void compute_exclusive_container_address_offsets(const type_info& exclusive_container_info, const type_tree* full_type) {
+void compute_exclusive_container_address_offsets(const type_info& exclusive_container_info, const type_tree* full_type, const string& location_for_error_messages) {
   container_metadata& metadata = get(Container_metadata, full_type);
   trace(9994, "transform") << "compute address offsets for exclusive container " << exclusive_container_info.name << end();
   for (int tag = 0;  tag < SIZE(exclusive_container_info.elements);  ++tag) {
     set<tag_condition_info> key;
     key.insert(tag_condition_info(/*tag is at offset*/0, tag));
-    append_addresses(/*skip tag offset*/1, variant_type(full_type, tag).type, metadata.address, key);
+    append_addresses(/*skip tag offset*/1, variant_type(full_type, tag).type, metadata.address, key, location_for_error_messages);
   }
 }
 
-void append_addresses(int base_offset, const type_tree* type, map<set<tag_condition_info>, set<address_element_info> >& out, const set<tag_condition_info>& key) {
+void append_addresses(int base_offset, const type_tree* type, map<set<tag_condition_info>, set<address_element_info> >& out, const set<tag_condition_info>& key, const string& location_for_error_messages) {
   if (is_mu_address(type)) {
     get_or_insert(out, key).insert(address_element_info(base_offset, new type_tree(*type->right)));
     return;
@@ -366,7 +366,7 @@ void append_addresses(int base_offset, const type_tree* type, map<set<tag_condit
         ++curr_offset;
       }
       else if (is_mu_container(element)) {
-        append_addresses(curr_offset, element.type, out, key);
+        append_addresses(curr_offset, element.type, out, key, location_for_error_messages);
         curr_offset += size_of(element);
       }
       else if (is_mu_exclusive_container(element)) {
@@ -376,7 +376,7 @@ void append_addresses(int base_offset, const type_tree* type, map<set<tag_condit
           set<tag_condition_info> new_key = key;
           new_key.insert(tag_condition_info(curr_offset, tag));
           if (!contains_key(out, new_key))
-            append_addresses(curr_offset+/*skip tag*/1, variant_type(element.type, tag).type, out, new_key);
+            append_addresses(curr_offset+/*skip tag*/1, variant_type(element.type, tag).type, out, new_key, location_for_error_messages);
         }
         curr_offset += size_of(element);
       }
@@ -391,7 +391,7 @@ void append_addresses(int base_offset, const type_tree* type, map<set<tag_condit
       set<tag_condition_info> new_key = key;
       new_key.insert(tag_condition_info(base_offset, tag));
       if (!contains_key(out, new_key))
-        append_addresses(base_offset+/*skip tag*/1, variant_type(type, tag).type, out, new_key);
+        append_addresses(base_offset+/*skip tag*/1, variant_type(type, tag).type, out, new_key, location_for_error_messages);
     }
   }
 }
@@ -409,9 +409,9 @@ void test_container_address_offsets_empty() {
   int old_size = SIZE(Container_metadata);
   // define a container with no addresses
   reagent r("x:point");
-  compute_container_sizes(r);  // need to first pre-populate the metadata
+  compute_container_sizes(r, "");  // need to first pre-populate the metadata
   // scan
-  compute_container_address_offsets(r);
+  compute_container_address_offsets(r, "");
   // global metadata contains just the entry for foo
   // no entries for non-container types or other junk
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
@@ -431,9 +431,9 @@ void test_container_address_offsets() {
       "  x:address:num\n"
       "]\n");
   reagent r("x:foo");
-  compute_container_sizes(r);  // need to first pre-populate the metadata
+  compute_container_sizes(r, "");  // need to first pre-populate the metadata
   // scan
-  compute_container_address_offsets(r);
+  compute_container_address_offsets(r, "");
   // global metadata contains just the entry for foo
   // no entries for non-container types or other junk
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
@@ -464,12 +464,12 @@ void test_container_address_offsets_2() {
       "  y:address:num\n"
       "]\n");
   reagent r("x:foo");
-  compute_container_sizes(r);  // need to first pre-populate the metadata
+  compute_container_sizes(r, "");  // need to first pre-populate the metadata
   // global metadata contains just the entry for foo
   // no entries for non-container types or other junk
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scan
-  compute_container_address_offsets(r);
+  compute_container_address_offsets(r, "");
   // compute_container_address_offsets creates no new entries
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // the reagent we scanned knows it has an address at offset 1
@@ -501,12 +501,12 @@ void test_container_address_offsets_nested() {
       "  f:foo\n"  // nested container containing address
       "]\n");
   reagent r("x:bar");
-  compute_container_sizes(r);  // need to first pre-populate the metadata
+  compute_container_sizes(r, "");  // need to first pre-populate the metadata
   // global metadata contains entries for bar and included types: point and foo
   // no entries for non-container types or other junk
   CHECK_EQ(SIZE(Container_metadata)-old_size, 3);
   // scan
-  compute_container_address_offsets(r);
+  compute_container_address_offsets(r, "");
   // the reagent we scanned knows it has an address at offset 2
   CHECK_EQ(SIZE(r.metadata.address), 1);
   CHECK(contains_key(r.metadata.address, set<tag_condition_info>()));
@@ -533,12 +533,12 @@ void test_container_address_offsets_from_address() {
       "  x:address:num\n"
       "]\n");
   reagent r("x:address:foo");
-  compute_container_sizes(r);  // need to first pre-populate the metadata
+  compute_container_sizes(r, "");  // need to first pre-populate the metadata
   // global metadata contains just the entry for foo
   // no entries for non-container types or other junk
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scan an address to the container
-  compute_container_address_offsets(r);
+  compute_container_address_offsets(r, "");
   // compute_container_address_offsets creates no new entries
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scanning precomputed metadata for the container
@@ -558,12 +558,12 @@ void test_container_address_offsets_from_array() {
       "  x:address:num\n"
       "]\n");
   reagent r("x:array:foo");
-  compute_container_sizes(r);  // need to first pre-populate the metadata
+  compute_container_sizes(r, "");  // need to first pre-populate the metadata
   // global metadata contains just the entry for foo
   // no entries for non-container types or other junk
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scan an array of the container
-  compute_container_address_offsets(r);
+  compute_container_address_offsets(r, "");
   // compute_container_address_offsets creates no new entries
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scanning precomputed metadata for the container
@@ -583,12 +583,12 @@ void test_container_address_offsets_from_address_to_array() {
       "  x:address:num\n"
       "]\n");
   reagent r("x:address:array:foo");
-  compute_container_sizes(r);  // need to first pre-populate the metadata
+  compute_container_sizes(r, "");  // need to first pre-populate the metadata
   // global metadata contains just the entry for foo
   // no entries for non-container types or other junk
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scan an address to an array of the container
-  compute_container_address_offsets(r);
+  compute_container_address_offsets(r, "");
   // compute_container_address_offsets creates no new entries
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scanning precomputed metadata for the container
@@ -608,12 +608,12 @@ void test_container_address_offsets_from_static_array() {
       "  x:address:num\n"
       "]\n");
   reagent r("x:array:foo:10");
-  compute_container_sizes(r);  // need to first pre-populate the metadata
+  compute_container_sizes(r, "");  // need to first pre-populate the metadata
   // global metadata contains just the entry for foo
   // no entries for non-container types or other junk
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scan a static array of the container
-  compute_container_address_offsets(r);
+  compute_container_address_offsets(r, "");
   // compute_container_address_offsets creates no new entries
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scanning precomputed metadata for the container
@@ -633,12 +633,12 @@ void test_container_address_offsets_from_address_to_static_array() {
       "  x:address:num\n"
       "]\n");
   reagent r("x:address:array:foo:10");
-  compute_container_sizes(r);  // need to first pre-populate the metadata
+  compute_container_sizes(r, "");  // need to first pre-populate the metadata
   // global metadata contains just the entry for foo
   // no entries for non-container types or other junk
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scan an address to a static array of the container
-  compute_container_address_offsets(r);
+  compute_container_address_offsets(r, "");
   // compute_container_address_offsets creates no new entries
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scanning precomputed metadata for the container
@@ -659,11 +659,11 @@ void test_container_address_offsets_from_repeated_address_and_array_types() {
       "]\n");
   // scan a deep nest of 'address' and 'array' types modifying a container
   reagent r("x:address:array:address:address:array:foo:10");
-  compute_container_sizes(r);  // need to first pre-populate the metadata
+  compute_container_sizes(r, "");  // need to first pre-populate the metadata
   // global metadata contains just the entry for foo
   // no entries for non-container types or other junk
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
-  compute_container_address_offsets(r);
+  compute_container_address_offsets(r, "");
   // compute_container_address_offsets creates no new entries
   CHECK_EQ(SIZE(Container_metadata)-old_size, 1);
   // scanning precomputed metadata for the container
diff --git a/055shape_shifting_container.cc b/055shape_shifting_container.cc
index 33746c46..044e7089 100644
--- a/055shape_shifting_container.cc
+++ b/055shape_shifting_container.cc
@@ -286,20 +286,20 @@ def main [
 +mem: storing 1 in location 4
 
 :(before "End element_type Special-cases")
-replace_type_ingredients(element, type, info);
+replace_type_ingredients(element, type, info, " while computing element type of container");
 :(before "Compute Container Size(element, full_type)")
-replace_type_ingredients(element, full_type, container_info);
+replace_type_ingredients(element, full_type, container_info, location_for_error_messages);
 :(before "Compute Exclusive Container Size(element, full_type)")
-replace_type_ingredients(element, full_type, exclusive_container_info);
+replace_type_ingredients(element, full_type, exclusive_container_info, location_for_error_messages);
 :(before "Compute Container Address Offset(element)")
-replace_type_ingredients(element, type, info);
+replace_type_ingredients(element, type, info, location_for_error_messages);
 if (contains_type_ingredient(element)) return;  // error raised elsewhere
 
 :(code)
-void replace_type_ingredients(reagent& element, const type_tree* caller_type, const type_info& info) {
+void replace_type_ingredients(reagent& element, const type_tree* caller_type, const type_info& info, const string& location_for_error_messages) {
   if (contains_type_ingredient(element)) {
     if (!caller_type->right)
-      raise << "illegal type " << names_to_string(caller_type) << " seems to be missing a type ingredient or three\n" << end();
+      raise << "illegal type " << names_to_string(caller_type) << " seems to be missing a type ingredient or three" << location_for_error_messages << '\n' << end();
     replace_type_ingredients(element.type, caller_type->right, info);
   }
 }
@@ -479,7 +479,7 @@ def main [
   10:foo:point <- merge 14, 15, 16
   1:num <- get 10:foo, 1:offset
 ]
-+error: illegal type "foo" seems to be missing a type ingredient or three
++error: illegal type "foo" seems to be missing a type ingredient or three in '1:num <- get 10:foo, 1:offset'
 
 //:: fix up previous layers
 
@@ -491,11 +491,11 @@ def main [
 const type_tree* root = root_type(type);
 type_info& info = get(Type, root->value);
 if (info.kind == CONTAINER) {
-  compute_container_sizes(info, type, pending_metadata);
+  compute_container_sizes(info, type, pending_metadata, location_for_error_messages);
   return;
 }
 if (info.kind == EXCLUSIVE_CONTAINER) {
-  compute_exclusive_container_sizes(info, type, pending_metadata);
+  compute_exclusive_container_sizes(info, type, pending_metadata, location_for_error_messages);
   return;
 }
 
@@ -506,7 +506,7 @@ void test_container_sizes_shape_shifting_container() {
       "  y:_t\n"
       "]\n");
   reagent r("x:foo:point");
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   CHECK_EQ(r.metadata.size, 3);
 }
 
@@ -516,10 +516,10 @@ void test_container_sizes_shape_shifting_exclusive_container() {
       "  y:_t\n"
       "]\n");
   reagent r("x:foo:point");
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   CHECK_EQ(r.metadata.size, 3);
   reagent r2("x:foo:num");
-  compute_container_sizes(r2);
+  compute_container_sizes(r2, "");
   CHECK_EQ(r2.metadata.size, 2);
 }
 
@@ -529,7 +529,7 @@ void test_container_sizes_compound_type_ingredient() {
       "  y:_t\n"
       "]\n");
   reagent r("x:foo:&:point");
-  compute_container_sizes(r);
+  compute_container_sizes(r, "");
   CHECK_EQ(r.metadata.size, 2);
   // scan also pre-computes metadata for type ingredient
   reagent point("x:point");
@@ -543,7 +543,7 @@ void test_container_sizes_recursive_shape_shifting_container() {
       "  y:&:foo:_t\n"
       "]\n");
   reagent r2("x:foo:num");
-  compute_container_sizes(r2);
+  compute_container_sizes(r2, "");
   CHECK_EQ(r2.metadata.size, 2);
 }
 
@@ -551,11 +551,11 @@ void test_container_sizes_recursive_shape_shifting_container() {
 const type_tree* root = root_type(type);
 type_info& info = get(Type, root->value);
 if (info.kind == CONTAINER) {
-  compute_container_address_offsets(info, type);
+  compute_container_address_offsets(info, type, location_for_error_messages);
   return;
 }
 if (info.kind == EXCLUSIVE_CONTAINER) {
-  compute_exclusive_container_address_offsets(info, type);
+  compute_exclusive_container_address_offsets(info, type, location_for_error_messages);
   return;
 }
 
@@ -566,8 +566,8 @@ void test_container_address_offsets_in_shape_shifting_container() {
       "  y:_t\n"
       "]\n");
   reagent r("x:foo:&:num");
-  compute_container_sizes(r);
-  compute_container_address_offsets(r);
+  compute_container_sizes(r, "");
+  compute_container_address_offsets(r, "");
   CHECK_EQ(SIZE(r.metadata.address), 1);
   CHECK(contains_key(r.metadata.address, set<tag_condition_info>()));
   set<address_element_info>& offset_info = get(r.metadata.address, set<tag_condition_info>());
@@ -588,8 +588,8 @@ void test_container_address_offsets_in_nested_shape_shifting_container() {
       "]\n");
   reagent r("x:bar:&:num");
   CLEAR_TRACE;
-  compute_container_sizes(r);
-  compute_container_address_offsets(r);
+  compute_container_sizes(r, "");
+  compute_container_address_offsets(r, "");
   CHECK_EQ(SIZE(r.metadata.address), 1);
   CHECK(contains_key(r.metadata.address, set<tag_condition_info>()));
   set<address_element_info>& offset_info = get(r.metadata.address, set<tag_condition_info>());
@@ -685,6 +685,6 @@ def main [
 :(before "End variant_type Special-cases")
 if (contains_type_ingredient(element)) {
   if (!type->right)
-    raise << "illegal type " << to_string(type) << " seems to be missing a type ingredient or three\n" << end();
+    raise << "illegal type " << to_string(type) << " seems to be missing a type ingredient or three while computing variant type of exclusive-container\n" << end();
   replace_type_ingredients(element.type, type->right, info);
 }