Basic support for switch payloads
This commit is contained in:
parent
a0f1795f2d
commit
9997535a3e
@ -1407,6 +1407,7 @@ pub const Declaration = union(enum) {
|
|||||||
},
|
},
|
||||||
switch_payload: struct {
|
switch_payload: struct {
|
||||||
node: *ast.Node.PointerPayload,
|
node: *ast.Node.PointerPayload,
|
||||||
|
switch_expr: *ast.Node,
|
||||||
items: []const *ast.Node,
|
items: []const *ast.Node,
|
||||||
},
|
},
|
||||||
label_decl: *ast.Node, // .id is While, For or Block (firstToken will be the label)
|
label_decl: *ast.Node, // .id is While, For or Block (firstToken will be the label)
|
||||||
@ -1484,8 +1485,40 @@ pub const DeclWithHandle = struct {
|
|||||||
bound_type_params,
|
bound_type_params,
|
||||||
),
|
),
|
||||||
.label_decl => return null,
|
.label_decl => return null,
|
||||||
// TODO Resolve switch payload types
|
.switch_payload => |pay| {
|
||||||
.switch_payload => |pay| return null,
|
if (pay.items.len == 0) return null;
|
||||||
|
// TODO Peer type resolution, we just use the first item for now.
|
||||||
|
const switch_expr_type = (try resolveTypeOfNodeInternal(store, arena, .{
|
||||||
|
.node = pay.switch_expr,
|
||||||
|
.handle = self.handle,
|
||||||
|
}, bound_type_params)) orelse return null;
|
||||||
|
if (!switch_expr_type.isUnionType())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (pay.items[0].cast(ast.Node.EnumLiteral)) |enum_lit| {
|
||||||
|
const scope = findContainerScope(.{ .node = switch_expr_type.type.data.other, .handle = switch_expr_type.handle }) orelse return null;
|
||||||
|
if (scope.decls.get(self.handle.tree.tokenSlice(enum_lit.name))) |candidate| {
|
||||||
|
switch (candidate.value) {
|
||||||
|
.ast_node => |node| {
|
||||||
|
if (node.cast(ast.Node.ContainerField)) |container_field| {
|
||||||
|
if (container_field.type_expr) |type_expr| {
|
||||||
|
return ((try resolveTypeOfNodeInternal(
|
||||||
|
store,
|
||||||
|
arena,
|
||||||
|
.{ .node = type_expr, .handle = switch_expr_type.handle },
|
||||||
|
bound_type_params,
|
||||||
|
)) orelse return null).instanceTypeVal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// @TODO
|
||||||
|
return null;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -2250,6 +2283,7 @@ fn makeScopeInternal(
|
|||||||
try scope.decls.putNoClobber(name, .{
|
try scope.decls.putNoClobber(name, .{
|
||||||
.switch_payload = .{
|
.switch_payload = .{
|
||||||
.node = ptr_payload,
|
.node = ptr_payload,
|
||||||
|
.switch_expr = switch_node.expr,
|
||||||
.items = case_node.itemsConst(),
|
.items = case_node.itemsConst(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user