| ... | @@ -897,18 +897,22 @@ pub fn arrayInitExpr( | ... | @@ -897,18 +897,22 @@ pub fn arrayInitExpr( |
| 897 | if (node_tags[array_type.ast.elem_count] == .identifier and | 897 | if (node_tags[array_type.ast.elem_count] == .identifier and |
| 898 | mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_")) | 898 | mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_")) |
| 899 | { | 899 | { |
| 900 | const tag: Zir.Inst.Tag = switch (node_tags[array_init.ast.type_expr]) { | | |
| 901 | .array_type => .array_type, | | |
| 902 | .array_type_sentinel => .array_type_sentinel, | | |
| 903 | else => unreachable, | | |
| 904 | }; | | |
| 905 | const len_inst = try gz.addInt(array_init.ast.elements.len); | 900 | const len_inst = try gz.addInt(array_init.ast.elements.len); |
| 906 | const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); | 901 | const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); |
| 907 | const array_type_inst = try gz.addBin(tag, len_inst, elem_type); | 902 | if (array_type.ast.sentinel == 0) { |
| 908 | break :inst .{ | 903 | const array_type_inst = try gz.addBin(.array_type, len_inst, elem_type); |
| 909 | .array = array_type_inst, | 904 | break :inst .{ |
| 910 | .elem = elem_type, | 905 | .array = array_type_inst, |
| 911 | }; | 906 | .elem = elem_type, |
| | 907 | }; |
| | 908 | } else { |
| | 909 | const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel); |
| | 910 | const array_type_inst = try gz.addArrayTypeSentinel(len_inst, elem_type, sentinel); |
| | 911 | break :inst .{ |
| | 912 | .array = array_type_inst, |
| | 913 | .elem = elem_type, |
| | 914 | }; |
| | 915 | } |
| 912 | } | 916 | } |
| 913 | } | 917 | } |
| 914 | const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr); | 918 | const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr); |
| ... | @@ -1053,11 +1057,33 @@ pub fn structInitExpr( | ... | @@ -1053,11 +1057,33 @@ pub fn structInitExpr( |
| 1053 | if (struct_init.ast.fields.len == 0) { | 1057 | if (struct_init.ast.fields.len == 0) { |
| 1054 | if (struct_init.ast.type_expr == 0) { | 1058 | if (struct_init.ast.type_expr == 0) { |
| 1055 | return rvalue(gz, scope, rl, .empty_struct, node); | 1059 | return rvalue(gz, scope, rl, .empty_struct, node); |
| 1056 | } else { | | |
| 1057 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | | |
| 1058 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); | | |
| 1059 | return rvalue(gz, scope, rl, result, node); | | |
| 1060 | } | 1060 | } |
| | 1061 | array: { |
| | 1062 | const node_tags = tree.nodes.items(.tag); |
| | 1063 | const main_tokens = tree.nodes.items(.main_token); |
| | 1064 | const array_type: ast.full.ArrayType = switch (node_tags[struct_init.ast.type_expr]) { |
| | 1065 | .array_type => tree.arrayType(struct_init.ast.type_expr), |
| | 1066 | .array_type_sentinel => tree.arrayTypeSentinel(struct_init.ast.type_expr), |
| | 1067 | else => break :array, |
| | 1068 | }; |
| | 1069 | // This intentionally does not support `@"_"` syntax. |
| | 1070 | if (node_tags[array_type.ast.elem_count] == .identifier and |
| | 1071 | mem.eql(u8, tree.tokenSlice(main_tokens[array_type.ast.elem_count]), "_")) |
| | 1072 | { |
| | 1073 | const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); |
| | 1074 | const array_type_inst = if (array_type.ast.sentinel == 0) blk: { |
| | 1075 | break :blk try gz.addBin(.array_type, .zero_usize, elem_type); |
| | 1076 | } else blk: { |
| | 1077 | const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel); |
| | 1078 | break :blk try gz.addArrayTypeSentinel(.zero_usize, elem_type, sentinel); |
| | 1079 | }; |
| | 1080 | const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node); |
| | 1081 | return rvalue(gz, scope, rl, result, node); |
| | 1082 | } |
| | 1083 | } |
| | 1084 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| | 1085 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); |
| | 1086 | return rvalue(gz, scope, rl, result, node); |
| 1061 | } | 1087 | } |
| 1062 | switch (rl) { | 1088 | switch (rl) { |
| 1063 | .discard => { | 1089 | .discard => { |
| ... | @@ -2278,7 +2304,6 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.I | ... | @@ -2278,7 +2304,6 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.I |
| 2278 | const node_datas = tree.nodes.items(.data); | 2304 | const node_datas = tree.nodes.items(.data); |
| 2279 | const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel); | 2305 | const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel); |
| 2280 | | 2306 | |
| 2281 | // TODO check for [_]T | | |
| 2282 | const len = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].lhs); | 2307 | const len = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].lhs); |
| 2283 | const elem_type = try typeExpr(gz, scope, extra.elem_type); | 2308 | const elem_type = try typeExpr(gz, scope, extra.elem_type); |
| 2284 | const sentinel = try expr(gz, scope, .{ .ty = elem_type }, extra.sentinel); | 2309 | const sentinel = try expr(gz, scope, .{ .ty = elem_type }, extra.sentinel); |