diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-04-27 22:28:55 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-04-27 22:28:55 -0700 |
commit | 5b22547bb352f6e5a98ddd8ff42f37861a8e16ea (patch) | |
tree | cf531cce10d5f570f55dd54a46361dad882a14f6 /058shape_shifting_recipe.cc | |
parent | b1ddb414006352b2d3af3652263a536acbd2702e (diff) | |
download | mu-5b22547bb352f6e5a98ddd8ff42f37861a8e16ea.tar.gz |
2880
Turns out we don't need a primitive to return an empty value of arbitrary type. Just create it on the heap using 'new'. But this uncovered *yet* another bug, sigh. When I specialize generic functions I was running all transforms on the generated functions after specialization completed. But there's one transform that includes code from elsewhere. If such code included type-ingredients -- kaboom. Now fixed and there's a test, so I've got that going for me which is nice.
Diffstat (limited to '058shape_shifting_recipe.cc')
-rw-r--r-- | 058shape_shifting_recipe.cc | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/058shape_shifting_recipe.cc b/058shape_shifting_recipe.cc index 6067fe7e..0384dd57 100644 --- a/058shape_shifting_recipe.cc +++ b/058shape_shifting_recipe.cc @@ -61,6 +61,8 @@ if (!candidates.empty()) { if (!variant.steps.empty()) { trace(9992, "transform") << "transforming new specialization: " << variant.name << end(); for (int t = 0; t < SIZE(Transform); ++t) { + // one exception: skip tangle, which would have already occurred inside new_variant above + if (Transform.at(t) == insert_fragments) continue; (*Transform.at(t))(new_recipe_ordinal); } } @@ -230,8 +232,14 @@ recipe_ordinal new_variant(recipe_ordinal exemplar, const instruction& inst, con recipe& new_recipe = get(Recipe, new_recipe_ordinal); new_recipe.name = new_name; trace(9993, "transform") << "switching " << inst.name << " to specialized " << header_label(new_recipe_ordinal) << end(); - // Since the exemplar never ran any transforms, we have to redo some of the - // work of the check_types_by_name transform while supporting type-ingredients. + + // Replace type ingredients with concrete types in new_recipe. + // + // preprocessing: micro-manage a couple of transforms + // a) perform tangle *before* replacing type ingredients, just in case + // inserted code involves type ingredients + insert_fragments(new_recipe_ordinal); + // b) do the work of check_types_by_name while supporting type-ingredients compute_type_names(new_recipe); // that gives enough information to replace type-ingredients with concrete types { @@ -1027,3 +1035,21 @@ def main [ foo *z ] # shouldn't crash + +:(scenario tangle_shape_shifting_recipe) +# shape-shifting recipe +def foo a:_elem [ + local-scope + load-ingredients + <label1> +] +# tangle some code that refers to the type ingredient +after <label1> [ + b:_elem <- copy a +] +# trigger specialization +def main [ + local-scope + foo 34 +] +$exit: 0 |