| author | |
| committer | |
| log | 29daf10639149bd023db0be4e04eaf154dce0f83 |
| tree | 13dc178febddc98b4cc72b6a4f341b796a2a008e |
| parent | 5a2620fcca55813d87000f3018e70509b1d325e0 |
4 files changed, 32 insertions(+), 46 deletions(-)
lib/std/zig/ast.zig+2-2| ... | ... | @@ -2054,7 +2054,7 @@ pub const full = struct { |
| 2054 | 2054 | return null; |
| 2055 | 2055 | } |
| 2056 | 2056 | const param_type = it.fn_proto.ast.params[it.param_i]; |
| 2057 | var tok_i = tree.firstToken(param_type) - 1; | |
| 2057 | var tok_i = it.tree.firstToken(param_type) - 1; | |
| 2058 | 2058 | while (true) : (tok_i -= 1) switch (token_tags[tok_i]) { |
| 2059 | 2059 | .colon => continue, |
| 2060 | 2060 | .identifier => name_token = tok_i, |
| ... | ... | @@ -2063,7 +2063,7 @@ pub const full = struct { |
| 2063 | 2063 | else => break, |
| 2064 | 2064 | }; |
| 2065 | 2065 | it.param_i += 1; |
| 2066 | it.tok_i = tree.lastToken(param_type) + 1; | |
| 2066 | it.tok_i = it.tree.lastToken(param_type) + 1; | |
| 2067 | 2067 | it.tok_flag = true; |
| 2068 | 2068 | return Param{ |
| 2069 | 2069 | .first_doc_comment = first_doc_comment, |
src/Module.zig+19-20| ... | ... | @@ -1223,19 +1223,6 @@ fn astgenAndSemaFn( |
| 1223 | 1223 | .{}, |
| 1224 | 1224 | ); |
| 1225 | 1225 | } |
| 1226 | const opt_cc: ?*zir.Inst = if (fn_proto.ast.callconv_expr != 0) cc: { | |
| 1227 | // TODO instead of enum literal type, this needs to be the | |
| 1228 | // std.builtin.CallingConvention enum. We need to implement importing other files | |
| 1229 | // and enums in order to fix this. | |
| 1230 | const src = token_starts[tree.firstToken(fn_proto.ast.callconv_expr)]; | |
| 1231 | const enum_lit_ty = try astgen.addZIRInstConst(mod, &fn_type_scope.base, src, .{ | |
| 1232 | .ty = Type.initTag(.type), | |
| 1233 | .val = Value.initTag(.enum_literal_type), | |
| 1234 | }); | |
| 1235 | break :cc try astgen.comptimeExpr(mod, &fn_type_scope.base, .{ | |
| 1236 | .ty = enum_lit_ty, | |
| 1237 | }, fn_proto.ast.callconv_expr); | |
| 1238 | } else null; | |
| 1239 | 1226 | |
| 1240 | 1227 | const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1; |
| 1241 | 1228 | if (token_tags[maybe_bang] == .bang) { |
| ... | ... | @@ -1247,13 +1234,24 @@ fn astgenAndSemaFn( |
| 1247 | 1234 | type_type_rl, |
| 1248 | 1235 | fn_proto.ast.return_type, |
| 1249 | 1236 | ); |
| 1250 | const fn_type_inst = if (opt_cc) |cc| | |
| 1251 | try astgen.addZirInstTag(mod, &fn_type_scope.base, fn_src, .fn_type_cc, .{ | |
| 1237 | const fn_type_inst = if (fn_proto.ast.callconv_expr != 0) cc: { | |
| 1238 | // TODO instead of enum literal type, this needs to be the | |
| 1239 | // std.builtin.CallingConvention enum. We need to implement importing other files | |
| 1240 | // and enums in order to fix this. | |
| 1241 | const src = token_starts[tree.firstToken(fn_proto.ast.callconv_expr)]; | |
| 1242 | const enum_lit_ty = try astgen.addZIRInstConst(mod, &fn_type_scope.base, src, .{ | |
| 1243 | .ty = Type.initTag(.type), | |
| 1244 | .val = Value.initTag(.enum_literal_type), | |
| 1245 | }); | |
| 1246 | const cc = try astgen.comptimeExpr(mod, &fn_type_scope.base, .{ | |
| 1247 | .ty = enum_lit_ty, | |
| 1248 | }, fn_proto.ast.callconv_expr); | |
| 1249 | break :cc try astgen.addZirInstTag(mod, &fn_type_scope.base, fn_src, .fn_type_cc, .{ | |
| 1252 | 1250 | .return_type = return_type_inst, |
| 1253 | 1251 | .param_types = param_types, |
| 1254 | 1252 | .cc = cc, |
| 1255 | }) | |
| 1256 | else | |
| 1253 | }); | |
| 1254 | } else | |
| 1257 | 1255 | try astgen.addZirInstTag(mod, &fn_type_scope.base, fn_src, .fn_type, .{ |
| 1258 | 1256 | .return_type = return_type_inst, |
| 1259 | 1257 | .param_types = param_types, |
| ... | ... | @@ -1362,13 +1360,13 @@ fn astgenAndSemaFn( |
| 1362 | 1360 | params_scope = &sub_scope.base; |
| 1363 | 1361 | } |
| 1364 | 1362 | |
| 1365 | try astgen.expr(mod, params_scope, .none, body_node); | |
| 1363 | _ = try astgen.expr(mod, params_scope, .none, body_node); | |
| 1366 | 1364 | |
| 1367 | 1365 | if (gen_scope.instructions.items.len == 0 or |
| 1368 | 1366 | !gen_scope.instructions.items[gen_scope.instructions.items.len - 1].tag.isNoReturn()) |
| 1369 | 1367 | { |
| 1370 | 1368 | const src = token_starts[tree.lastToken(body_node)]; |
| 1371 | _ = try astgen.addZIRNoOp(mod, &gen_scope.base, src, .returnvoid); | |
| 1369 | _ = try astgen.addZIRNoOp(mod, &gen_scope.base, src, .return_void); | |
| 1372 | 1370 | } |
| 1373 | 1371 | |
| 1374 | 1372 | if (std.builtin.mode == .Debug and mod.comp.verbose_ir) { |
| ... | ... | @@ -1542,6 +1540,7 @@ fn astgenAndSemaVarDecl( |
| 1542 | 1540 | .decl = decl, |
| 1543 | 1541 | .arena = &gen_scope_arena.allocator, |
| 1544 | 1542 | .parent = &decl.container.base, |
| 1543 | .force_comptime = true, | |
| 1545 | 1544 | }; |
| 1546 | 1545 | defer gen_scope.instructions.deinit(mod.gpa); |
| 1547 | 1546 | |
| ... | ... | @@ -1600,7 +1599,7 @@ fn astgenAndSemaVarDecl( |
| 1600 | 1599 | } else if (!is_extern) { |
| 1601 | 1600 | return mod.failTok( |
| 1602 | 1601 | &block_scope.base, |
| 1603 | tree.firstToken(var_decl), | |
| 1602 | var_decl.ast.mut_token, | |
| 1604 | 1603 | "variables must be initialized", |
| 1605 | 1604 | .{}, |
| 1606 | 1605 | ); |
src/astgen.zig+2-15| ... | ... | @@ -539,6 +539,7 @@ pub fn comptimeExpr( |
| 539 | 539 | } |
| 540 | 540 | |
| 541 | 541 | const tree = parent_scope.tree(); |
| 542 | const token_starts = tree.tokens.items(.start); | |
| 542 | 543 | |
| 543 | 544 | // Make a scope to collect generated instructions in the sub-expression. |
| 544 | 545 | var block_scope: Scope.GenZIR = .{ |
| ... | ... | @@ -693,7 +694,7 @@ pub fn blockExpr( |
| 693 | 694 | rl: ResultLoc, |
| 694 | 695 | block_node: ast.Node.Index, |
| 695 | 696 | statements: []const ast.Node.Index, |
| 696 | ) InnerError!void { | |
| 697 | ) InnerError!*zir.Inst { | |
| 697 | 698 | const tracy = trace(@src()); |
| 698 | 699 | defer tracy.end(); |
| 699 | 700 | |
| ... | ... | @@ -1174,20 +1175,6 @@ fn negation( |
| 1174 | 1175 | return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); |
| 1175 | 1176 | } |
| 1176 | 1177 | |
| 1177 | fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir.Inst { | |
| 1178 | const tree = scope.tree(); | |
| 1179 | const src = token_starts[node.op_token]; | |
| 1180 | return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, switch (tree.token_ids[node.op_token]) { | |
| 1181 | .Asterisk, .AsteriskAsterisk => .One, | |
| 1182 | // TODO stage1 type inference bug | |
| 1183 | .LBracket => @as(std.builtin.TypeInfo.Pointer.Size, switch (tree.token_ids[node.op_token + 2]) { | |
| 1184 | .identifier => .C, | |
| 1185 | else => .Many, | |
| 1186 | }), | |
| 1187 | else => unreachable, | |
| 1188 | }); | |
| 1189 | } | |
| 1190 | ||
| 1191 | 1178 | fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, rhs: *ast.Node, size: std.builtin.TypeInfo.Pointer.Size) InnerError!*zir.Inst { |
| 1192 | 1179 | const simple = ptr_info.allowzero_token == null and |
| 1193 | 1180 | ptr_info.align_info == null and |
src/zir_sema.zig+9-9| ... | ... | @@ -981,8 +981,8 @@ fn zirCall(mod: *Module, scope: *Scope, inst: *zir.Inst.Call) InnerError!*Inst { |
| 981 | 981 | const ret_type = func.ty.fnReturnType(); |
| 982 | 982 | |
| 983 | 983 | const b = try mod.requireFunctionBlock(scope, inst.base.src); |
| 984 | const is_comptime_call = b.is_comptime or inst.kw_args.modifier == .compile_time; | |
| 985 | const is_inline_call = is_comptime_call or inst.kw_args.modifier == .always_inline or | |
| 984 | const is_comptime_call = b.is_comptime or inst.positionals.modifier == .compile_time; | |
| 985 | const is_inline_call = is_comptime_call or inst.positionals.modifier == .always_inline or | |
| 986 | 986 | func.ty.fnCallingConvention() == .Inline; |
| 987 | 987 | if (is_inline_call) { |
| 988 | 988 | const func_val = try mod.resolveConstValue(scope, func); |
| ... | ... | @@ -1668,13 +1668,13 @@ fn zirSwitchBr(mod: *Module, scope: *Scope, inst: *zir.Inst.SwitchBr, ref: bool) |
| 1668 | 1668 | |
| 1669 | 1669 | fn validateSwitch(mod: *Module, scope: *Scope, target: *Inst, inst: *zir.Inst.SwitchBr) InnerError!void { |
| 1670 | 1670 | // validate usage of '_' prongs |
| 1671 | if (inst.kw_args.special_prong == .underscore and target.ty.zigTypeTag() != .Enum) { | |
| 1671 | if (inst.positionals.special_prong == .underscore and target.ty.zigTypeTag() != .Enum) { | |
| 1672 | 1672 | return mod.fail(scope, inst.base.src, "'_' prong only allowed when switching on non-exhaustive enums", .{}); |
| 1673 | 1673 | // TODO notes "'_' prong here" inst.positionals.cases[last].src |
| 1674 | 1674 | } |
| 1675 | 1675 | |
| 1676 | 1676 | // check that target type supports ranges |
| 1677 | if (inst.kw_args.range) |range_inst| { | |
| 1677 | if (inst.positionals.range) |range_inst| { | |
| 1678 | 1678 | switch (target.ty.zigTypeTag()) { |
| 1679 | 1679 | .Int, .ComptimeInt => {}, |
| 1680 | 1680 | else => { |
| ... | ... | @@ -1725,14 +1725,14 @@ fn validateSwitch(mod: *Module, scope: *Scope, target: *Inst, inst: *zir.Inst.Sw |
| 1725 | 1725 | const start = try target.ty.minInt(&arena, mod.getTarget()); |
| 1726 | 1726 | const end = try target.ty.maxInt(&arena, mod.getTarget()); |
| 1727 | 1727 | if (try range_set.spans(start, end)) { |
| 1728 | if (inst.kw_args.special_prong == .@"else") { | |
| 1728 | if (inst.positionals.special_prong == .@"else") { | |
| 1729 | 1729 | return mod.fail(scope, inst.base.src, "unreachable else prong, all cases already handled", .{}); |
| 1730 | 1730 | } |
| 1731 | 1731 | return; |
| 1732 | 1732 | } |
| 1733 | 1733 | } |
| 1734 | 1734 | |
| 1735 | if (inst.kw_args.special_prong != .@"else") { | |
| 1735 | if (inst.positionals.special_prong != .@"else") { | |
| 1736 | 1736 | return mod.fail(scope, inst.base.src, "switch must handle all possibilities", .{}); |
| 1737 | 1737 | } |
| 1738 | 1738 | }, |
| ... | ... | @@ -1752,15 +1752,15 @@ fn validateSwitch(mod: *Module, scope: *Scope, target: *Inst, inst: *zir.Inst.Sw |
| 1752 | 1752 | return mod.fail(scope, item.src, "duplicate switch value", .{}); |
| 1753 | 1753 | } |
| 1754 | 1754 | } |
| 1755 | if ((true_count + false_count < 2) and inst.kw_args.special_prong != .@"else") { | |
| 1755 | if ((true_count + false_count < 2) and inst.positionals.special_prong != .@"else") { | |
| 1756 | 1756 | return mod.fail(scope, inst.base.src, "switch must handle all possibilities", .{}); |
| 1757 | 1757 | } |
| 1758 | if ((true_count + false_count == 2) and inst.kw_args.special_prong == .@"else") { | |
| 1758 | if ((true_count + false_count == 2) and inst.positionals.special_prong == .@"else") { | |
| 1759 | 1759 | return mod.fail(scope, inst.base.src, "unreachable else prong, all cases already handled", .{}); |
| 1760 | 1760 | } |
| 1761 | 1761 | }, |
| 1762 | 1762 | .EnumLiteral, .Void, .Fn, .Pointer, .Type => { |
| 1763 | if (inst.kw_args.special_prong != .@"else") { | |
| 1763 | if (inst.positionals.special_prong != .@"else") { | |
| 1764 | 1764 | return mod.fail(scope, inst.base.src, "else prong required when switching on type '{}'", .{target.ty}); |
| 1765 | 1765 | } |
| 1766 | 1766 |