summaryrefslogtreecommitdiff
path: root/src/passes/Flatten.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/Flatten.cpp')
-rw-r--r--src/passes/Flatten.cpp30
1 files changed, 29 insertions, 1 deletions
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp
index 39c97b133..c8f731d64 100644
--- a/src/passes/Flatten.cpp
+++ b/src/passes/Flatten.cpp
@@ -17,8 +17,27 @@
//
// Flattens code into "Flat IR" form. See ir/flat.h.
//
-// TODO: handle non-nullability
+// TODO: handle non-nullability. for example:
//
+// (module
+// (type $none (func))
+// (func $foo
+// (drop
+// (block (result funcref (ref $none))
+// (tuple.make
+// (ref.null func)
+// (ref.func $foo)
+// )
+// )
+// )
+// )
+// )
+//
+// The tuple has a non-nullable type, and so it cannot be set to a local. We
+// would need to split up the tuple and reconstruct it later, but that would
+// require allowing tuple operations in more nested places than Flat IR allows
+// today. For now, error on this; eventually changes in the spec regarding
+// null-nullability may make this easier.
#include <ir/branch-utils.h>
#include <ir/effects.h>
@@ -319,6 +338,15 @@ struct Flatten
curr->body = getPreludesWithExpression(originalBody, curr->body);
// New locals we added may be non-nullable.
TypeUpdating::handleNonNullableLocals(curr, *getModule());
+ // We cannot handle non-nullable tuples currently, see the comment at the
+ // top of the file.
+ for (auto type : curr->vars) {
+ if (!type.isDefaultable()) {
+ Fatal() << "Flatten was forced to add a local of a type it cannot "
+ "handle yet: "
+ << type;
+ }
+ }
}
private: