feat: materialize address-free compile-time untagged unions
Snapshot full union storage rather than choosing an overlapping field. Preserve structural union source syntax independently of nominal identity so direct literal arguments materialize and share normalized specialization keys. Reject uninitialized bytes and address-bearing member layouts.
This commit is contained in:
+24
-1
@@ -83,6 +83,7 @@ ExprKind :: enum {
|
||||
try_expr
|
||||
catch_expr
|
||||
typed_constant
|
||||
union_constant
|
||||
comptime_expr
|
||||
literal_void
|
||||
literal_undefined
|
||||
@@ -196,6 +197,7 @@ NodeKind :: enum {
|
||||
stmt_errdefer
|
||||
stmt_block
|
||||
expr_typed_constant
|
||||
expr_union_constant
|
||||
expr_comptime
|
||||
literal_float_value
|
||||
literal_void
|
||||
@@ -611,6 +613,17 @@ add_typed_constant proc(
|
||||
}, at)
|
||||
}
|
||||
|
||||
#! retains an untagged union's complete native-layout bytes as a string literal.
|
||||
add_union_constant proc(
|
||||
builder @mut Builder, at Span, type, bytes NodeId,
|
||||
) NodeId ! mem.AllocError {
|
||||
return try add_node(builder, Node{
|
||||
kind = .expr_union_constant,
|
||||
data0 = NodeData{ node_id = type },
|
||||
data1 = NodeData{ node_id = bytes },
|
||||
}, at)
|
||||
}
|
||||
|
||||
add_comptime_expr proc(builder @mut Builder, at Span, operand NodeId) NodeId ! mem.AllocError {
|
||||
return try add_node(builder, Node{
|
||||
kind = .expr_comptime,
|
||||
@@ -1599,6 +1612,7 @@ expression_kind proc(kind NodeKind) ExprKind {
|
||||
.expr_try: .try_expr
|
||||
.expr_catch: .catch_expr
|
||||
.expr_typed_constant: .typed_constant
|
||||
.expr_union_constant: .union_constant
|
||||
.expr_comptime: .comptime_expr
|
||||
.expr_block: .block_expr
|
||||
.literal_float_value: .literal_float
|
||||
@@ -1652,6 +1666,15 @@ typed_constant proc(tree @Tree, id NodeId) TypedConstantView {
|
||||
}
|
||||
}
|
||||
|
||||
union_constant proc(tree @Tree, id NodeId) TypedConstantView {
|
||||
node :: get_node(&tree.storage, id)
|
||||
debug.assert(node.kind == .expr_union_constant)
|
||||
return TypedConstantView{
|
||||
type = node.data0.node_id,
|
||||
value = node.data1.node_id,
|
||||
}
|
||||
}
|
||||
|
||||
catch_expr proc(tree @Tree, id NodeId) CatchExprView {
|
||||
node :: get_node(&tree.storage, id)
|
||||
debug.assert(node.kind == .expr_catch)
|
||||
@@ -2007,7 +2030,7 @@ node_layout proc(node Node) NodeLayout {
|
||||
.literal_int, .literal_float, .literal_float_value, .literal_string, .literal_bool, .literal_null,
|
||||
.literal_void, .literal_undefined, .expr_identifier, .invalid_expr: {}
|
||||
.expr_unary: layout.direct_children = 2
|
||||
.expr_binary, .expr_range, .expr_index, .expr_selection, .expr_typed_constant,
|
||||
.expr_binary, .expr_range, .expr_index, .expr_selection, .expr_typed_constant, .expr_union_constant,
|
||||
.expr_fallible_type, .expr_sum_type, .expr_array_type, .expr_slice_type:
|
||||
layout.direct_children = 6
|
||||
.expr_pointer_type: layout.direct_children = 4
|
||||
|
||||
Reference in New Issue
Block a user