authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-09 06:13:47-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-06-09 06:13:47-04:00
loga3f05b80f1c26ca905e01c6d3a8a288a9f1d9e25
tree1bb04bf9a99acb6619fae6f2d550672c1249e55c
parent29dd9a58808f54423af8202049419f20aa362711
parentf4d5fcde727d93da9ebe17a27cc62270545ccda6
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11827 from ziglang/stage2-behavior

stage2: enhancements aimed at more behavior tests passing

11 files changed, 247 insertions(+), 105 deletions(-)

src/AstGen.zig+170-58
......@@ -45,6 +45,17 @@ fn_block: ?*GenZir = null,
4545imports: std.AutoArrayHashMapUnmanaged(u32, Ast.TokenIndex) = .{},
4646/// Used for temporary storage when building payloads.
4747scratch: std.ArrayListUnmanaged(u32) = .{},
48/// Whenever a `ref` instruction is needed, it is created and saved in this
49/// table instead of being immediately appended to the current block body.
50/// Then, when the instruction is being added to the parent block (typically from
51/// setBlockBody), if it has a ref_table entry, then the ref instruction is added
52/// there. This makes sure two properties are upheld:
53/// 1. All pointers to the same locals return the same address. This is required
54/// to be compliant with the language specification.
55/// 2. `ref` instructions will dominate their uses. This is a required property
56/// of ZIR.
57/// The key is the ref operand; the value is the ref instruction.
58ref_table: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{},
4859
4960const InnerError = error{ OutOfMemory, AnalysisFail };
5061
......@@ -199,6 +210,7 @@ pub fn deinit(astgen: *AstGen, gpa: Allocator) void {
199210 astgen.compile_errors.deinit(gpa);
200211 astgen.imports.deinit(gpa);
201212 astgen.scratch.deinit(gpa);
213 astgen.ref_table.deinit(gpa);
202214}
203215
204216pub const ResultLoc = union(enum) {
......@@ -4216,11 +4228,12 @@ fn structDeclInner(
42164228 }
42174229
42184230 const body = block_scope.instructionsSlice();
4231 const body_len = astgen.countBodyLenAfterFixups(body);
42194232
42204233 try gz.setStruct(decl_inst, .{
42214234 .src_node = node,
42224235 .layout = layout,
4223 .body_len = @intCast(u32, body.len),
4236 .body_len = body_len,
42244237 .fields_len = field_count,
42254238 .decls_len = decl_count,
42264239 .known_non_opv = known_non_opv,
......@@ -4230,9 +4243,9 @@ fn structDeclInner(
42304243 wip_members.finishBits(bits_per_field);
42314244 const decls_slice = wip_members.declsSlice();
42324245 const fields_slice = wip_members.fieldsSlice();
4233 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len + body.len + fields_slice.len);
4246 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len + body_len + fields_slice.len);
42344247 astgen.extra.appendSliceAssumeCapacity(decls_slice);
4235 astgen.extra.appendSliceAssumeCapacity(body);
4248 astgen.appendBodyWithFixups(body);
42364249 astgen.extra.appendSliceAssumeCapacity(fields_slice);
42374250
42384251 block_scope.unstack();
......@@ -4364,12 +4377,13 @@ fn unionDeclInner(
43644377 }
43654378
43664379 const body = block_scope.instructionsSlice();
4380 const body_len = astgen.countBodyLenAfterFixups(body);
43674381
43684382 try gz.setUnion(decl_inst, .{
43694383 .src_node = node,
43704384 .layout = layout,
43714385 .tag_type = arg_inst,
4372 .body_len = @intCast(u32, body.len),
4386 .body_len = body_len,
43734387 .fields_len = field_count,
43744388 .decls_len = decl_count,
43754389 .auto_enum_tag = have_auto_enum,
......@@ -4378,9 +4392,9 @@ fn unionDeclInner(
43784392 wip_members.finishBits(bits_per_field);
43794393 const decls_slice = wip_members.declsSlice();
43804394 const fields_slice = wip_members.fieldsSlice();
4381 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len + body.len + fields_slice.len);
4395 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len + body_len + fields_slice.len);
43824396 astgen.extra.appendSliceAssumeCapacity(decls_slice);
4383 astgen.extra.appendSliceAssumeCapacity(body);
4397 astgen.appendBodyWithFixups(body);
43844398 astgen.extra.appendSliceAssumeCapacity(fields_slice);
43854399
43864400 block_scope.unstack();
......@@ -4616,12 +4630,13 @@ fn containerDecl(
46164630 }
46174631
46184632 const body = block_scope.instructionsSlice();
4633 const body_len = astgen.countBodyLenAfterFixups(body);
46194634
46204635 try gz.setEnum(decl_inst, .{
46214636 .src_node = node,
46224637 .nonexhaustive = nonexhaustive,
46234638 .tag_type = arg_inst,
4624 .body_len = @intCast(u32, body.len),
4639 .body_len = body_len,
46254640 .fields_len = @intCast(u32, counts.total_fields),
46264641 .decls_len = @intCast(u32, counts.decls),
46274642 });
......@@ -4629,9 +4644,9 @@ fn containerDecl(
46294644 wip_members.finishBits(bits_per_field);
46304645 const decls_slice = wip_members.declsSlice();
46314646 const fields_slice = wip_members.fieldsSlice();
4632 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len + body.len + fields_slice.len);
4647 try astgen.extra.ensureUnusedCapacity(gpa, decls_slice.len + body_len + fields_slice.len);
46334648 astgen.extra.appendSliceAssumeCapacity(decls_slice);
4634 astgen.extra.appendSliceAssumeCapacity(body);
4649 astgen.appendBodyWithFixups(body);
46354650 astgen.extra.appendSliceAssumeCapacity(fields_slice);
46364651
46374652 block_scope.unstack();
......@@ -5403,10 +5418,12 @@ fn setCondBrPayload(
54035418 const astgen = then_scope.astgen;
54045419 const then_body = then_scope.instructionsSliceUpto(else_scope);
54055420 const else_body = else_scope.instructionsSlice();
5406 const then_body_len = @intCast(u32, then_body.len + @boolToInt(then_break != 0));
5407 const else_body_len = @intCast(u32, else_body.len + @boolToInt(else_break != 0));
5408 try astgen.extra.ensureUnusedCapacity(astgen.gpa, @typeInfo(Zir.Inst.CondBr).Struct.fields.len +
5409 then_body_len + else_body_len);
5421 const then_body_len = astgen.countBodyLenAfterFixups(then_body) + @boolToInt(then_break != 0);
5422 const else_body_len = astgen.countBodyLenAfterFixups(else_body) + @boolToInt(else_break != 0);
5423 try astgen.extra.ensureUnusedCapacity(
5424 astgen.gpa,
5425 @typeInfo(Zir.Inst.CondBr).Struct.fields.len + then_body_len + else_body_len,
5426 );
54105427
54115428 const zir_datas = astgen.instructions.items(.data);
54125429 zir_datas[condbr].pl_node.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.CondBr{
......@@ -5414,9 +5431,9 @@ fn setCondBrPayload(
54145431 .then_body_len = then_body_len,
54155432 .else_body_len = else_body_len,
54165433 });
5417 astgen.extra.appendSliceAssumeCapacity(then_body);
5434 astgen.appendBodyWithFixups(then_body);
54185435 if (then_break != 0) astgen.extra.appendAssumeCapacity(then_break);
5419 astgen.extra.appendSliceAssumeCapacity(else_body);
5436 astgen.appendBodyWithFixups(else_body);
54205437 if (else_break != 0) astgen.extra.appendAssumeCapacity(else_break);
54215438}
54225439
......@@ -5437,10 +5454,12 @@ fn setCondBrPayloadElideBlockStorePtr(
54375454 const else_body = else_scope.instructionsSlice();
54385455 const has_then_break = then_break != 0;
54395456 const has_else_break = else_break != 0;
5440 const then_body_len = @intCast(u32, then_body.len + @boolToInt(has_then_break));
5441 const else_body_len = @intCast(u32, else_body.len + @boolToInt(has_else_break));
5442 try astgen.extra.ensureUnusedCapacity(astgen.gpa, @typeInfo(Zir.Inst.CondBr).Struct.fields.len +
5443 then_body_len + else_body_len);
5457 const then_body_len = astgen.countBodyLenAfterFixups(then_body) + @boolToInt(has_then_break);
5458 const else_body_len = astgen.countBodyLenAfterFixups(else_body) + @boolToInt(has_else_break);
5459 try astgen.extra.ensureUnusedCapacity(
5460 astgen.gpa,
5461 @typeInfo(Zir.Inst.CondBr).Struct.fields.len + then_body_len + else_body_len,
5462 );
54445463
54455464 const zir_tags = astgen.instructions.items(.tag);
54465465 const zir_datas = astgen.instructions.items(.data);
......@@ -5475,7 +5494,7 @@ fn setCondBrPayloadElideBlockStorePtr(
54755494 continue;
54765495 }
54775496 }
5478 astgen.extra.appendAssumeCapacity(src_inst);
5497 appendPossiblyRefdBodyInst(astgen, &astgen.extra, src_inst);
54795498 }
54805499 if (has_then_break) astgen.extra.appendAssumeCapacity(then_break);
54815500
......@@ -5495,7 +5514,7 @@ fn setCondBrPayloadElideBlockStorePtr(
54955514 continue;
54965515 }
54975516 }
5498 astgen.extra.appendAssumeCapacity(src_inst);
5517 appendPossiblyRefdBodyInst(astgen, &astgen.extra, src_inst);
54995518 }
55005519 if (has_else_break) astgen.extra.appendAssumeCapacity(else_break);
55015520}
......@@ -6249,8 +6268,10 @@ fn switchExpr(
62496268 }
62506269
62516270 const case_slice = case_scope.instructionsSlice();
6252 payloads.items[body_len_index] = @intCast(u32, case_slice.len);
6253 try payloads.appendSlice(gpa, case_slice);
6271 const body_len = astgen.countBodyLenAfterFixups(case_slice);
6272 try payloads.ensureUnusedCapacity(gpa, body_len);
6273 payloads.items[body_len_index] = body_len;
6274 appendBodyWithFixupsArrayList(astgen, payloads, case_slice);
62546275 }
62556276 }
62566277 // Now that the item expressions are generated we can add this.
......@@ -7043,10 +7064,11 @@ fn typeOf(
70437064 node: Ast.Node.Index,
70447065 args: []const Ast.Node.Index,
70457066) InnerError!Zir.Inst.Ref {
7067 const astgen = gz.astgen;
70467068 if (args.len < 1) {
7047 return gz.astgen.failNode(node, "expected at least 1 argument, found 0", .{});
7069 return astgen.failNode(node, "expected at least 1 argument, found 0", .{});
70487070 }
7049 const gpa = gz.astgen.gpa;
7071 const gpa = astgen.gpa;
70507072 if (args.len == 1) {
70517073 const typeof_inst = try gz.makeBlockInst(.typeof_builtin, node);
70527074
......@@ -7065,7 +7087,7 @@ fn typeOf(
70657087 return rvalue(gz, rl, indexToRef(typeof_inst), node);
70667088 }
70677089 const payload_size: u32 = std.meta.fields(Zir.Inst.TypeOfPeer).len;
7068 const payload_index = try reserveExtra(gz.astgen, payload_size + args.len);
7090 const payload_index = try reserveExtra(astgen, payload_size + args.len);
70697091 var args_index = payload_index + payload_size;
70707092
70717093 const typeof_inst = try gz.addExtendedMultiOpPayloadIndex(.typeof_peer, payload_index, args.len);
......@@ -7075,17 +7097,19 @@ fn typeOf(
70757097
70767098 for (args) |arg, i| {
70777099 const param_ref = try reachableExpr(&typeof_scope, &typeof_scope.base, .none, arg, node);
7078 gz.astgen.extra.items[args_index + i] = @enumToInt(param_ref);
7100 astgen.extra.items[args_index + i] = @enumToInt(param_ref);
70797101 }
70807102 _ = try typeof_scope.addBreak(.break_inline, refToIndex(typeof_inst).?, .void_value);
70817103
70827104 const body = typeof_scope.instructionsSlice();
7083 gz.astgen.setExtra(payload_index, Zir.Inst.TypeOfPeer{
7084 .body_len = @intCast(u32, body.len),
7085 .body_index = @intCast(u32, gz.astgen.extra.items.len),
7105 const body_len = astgen.countBodyLenAfterFixups(body);
7106 astgen.setExtra(payload_index, Zir.Inst.TypeOfPeer{
7107 .body_len = @intCast(u32, body_len),
7108 .body_index = @intCast(u32, astgen.extra.items.len),
70867109 .src_node = gz.nodeIndexToRelative(node),
70877110 });
7088 try gz.astgen.extra.appendSlice(gpa, body);
7111 try astgen.extra.ensureUnusedCapacity(gpa, body_len);
7112 astgen.appendBodyWithFixups(body);
70897113 typeof_scope.unstack();
70907114
70917115 return rvalue(gz, rl, typeof_inst, node);
......@@ -9032,9 +9056,22 @@ fn rvalue(
90329056 },
90339057 .ref => {
90349058 // We need a pointer but we have a value.
9035 const tree = gz.astgen.tree;
9059 // Unfortunately it's not quite as simple as directly emitting a ref
9060 // instruction here because we need subsequent address-of operator on
9061 // const locals to return the same address.
9062 const astgen = gz.astgen;
9063 const tree = astgen.tree;
90369064 const src_token = tree.firstToken(src_node);
9037 return gz.addUnTok(.ref, result, src_token);
9065 const result_index = refToIndex(result) orelse
9066 return gz.addUnTok(.ref, result, src_token);
9067 const zir_tags = gz.astgen.instructions.items(.tag);
9068 if (zir_tags[result_index].isParam())
9069 return gz.addUnTok(.ref, result, src_token);
9070 const gop = try astgen.ref_table.getOrPut(astgen.gpa, result_index);
9071 if (!gop.found_existing) {
9072 gop.value_ptr.* = try gz.makeUnTok(.ref, result, src_token);
9073 }
9074 return indexToRef(gop.value_ptr.*);
90389075 },
90399076 .ty => |ty_inst| {
90409077 // Quickly eliminate some common, unnecessary type coercion.
......@@ -9976,43 +10013,58 @@ const GenZir = struct {
997610013
997710014 /// Assumes nothing stacked on `gz`. Unstacks `gz`.
997810015 fn setBoolBrBody(gz: *GenZir, inst: Zir.Inst.Index) !void {
9979 const gpa = gz.astgen.gpa;
10016 const astgen = gz.astgen;
10017 const gpa = astgen.gpa;
998010018 const body = gz.instructionsSlice();
9981 try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Block).Struct.fields.len + body.len);
9982 const zir_datas = gz.astgen.instructions.items(.data);
9983 zir_datas[inst].bool_br.payload_index = gz.astgen.addExtraAssumeCapacity(
9984 Zir.Inst.Block{ .body_len = @intCast(u32, body.len) },
10019 const body_len = astgen.countBodyLenAfterFixups(body);
10020 try astgen.extra.ensureUnusedCapacity(
10021 gpa,
10022 @typeInfo(Zir.Inst.Block).Struct.fields.len + body_len,
998510023 );
9986 gz.astgen.extra.appendSliceAssumeCapacity(body);
10024 const zir_datas = astgen.instructions.items(.data);
10025 zir_datas[inst].bool_br.payload_index = astgen.addExtraAssumeCapacity(
10026 Zir.Inst.Block{ .body_len = body_len },
10027 );
10028 astgen.appendBodyWithFixups(body);
998710029 gz.unstack();
998810030 }
998910031
999010032 /// Assumes nothing stacked on `gz`. Unstacks `gz`.
999110033 fn setBlockBody(gz: *GenZir, inst: Zir.Inst.Index) !void {
9992 const gpa = gz.astgen.gpa;
10034 const astgen = gz.astgen;
10035 const gpa = astgen.gpa;
999310036 const body = gz.instructionsSlice();
9994 try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Block).Struct.fields.len + body.len);
9995 const zir_datas = gz.astgen.instructions.items(.data);
9996 zir_datas[inst].pl_node.payload_index = gz.astgen.addExtraAssumeCapacity(
9997 Zir.Inst.Block{ .body_len = @intCast(u32, body.len) },
10037 const body_len = astgen.countBodyLenAfterFixups(body);
10038 try astgen.extra.ensureUnusedCapacity(
10039 gpa,
10040 @typeInfo(Zir.Inst.Block).Struct.fields.len + body_len,
10041 );
10042 const zir_datas = astgen.instructions.items(.data);
10043 zir_datas[inst].pl_node.payload_index = astgen.addExtraAssumeCapacity(
10044 Zir.Inst.Block{ .body_len = body_len },
999810045 );
9999 gz.astgen.extra.appendSliceAssumeCapacity(body);
10046 astgen.appendBodyWithFixups(body);
1000010047 gz.unstack();
1000110048 }
1000210049
1000310050 /// Assumes nothing stacked on `gz`. Unstacks `gz`.
1000410051 fn setTryBody(gz: *GenZir, inst: Zir.Inst.Index, operand: Zir.Inst.Ref) !void {
10005 const gpa = gz.astgen.gpa;
10052 const astgen = gz.astgen;
10053 const gpa = astgen.gpa;
1000610054 const body = gz.instructionsSlice();
10007 try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Try).Struct.fields.len + body.len);
10008 const zir_datas = gz.astgen.instructions.items(.data);
10009 zir_datas[inst].pl_node.payload_index = gz.astgen.addExtraAssumeCapacity(
10055 const body_len = astgen.countBodyLenAfterFixups(body);
10056 try astgen.extra.ensureUnusedCapacity(
10057 gpa,
10058 @typeInfo(Zir.Inst.Try).Struct.fields.len + body_len,
10059 );
10060 const zir_datas = astgen.instructions.items(.data);
10061 zir_datas[inst].pl_node.payload_index = astgen.addExtraAssumeCapacity(
1001010062 Zir.Inst.Try{
1001110063 .operand = operand,
10012 .body_len = @intCast(u32, body.len),
10064 .body_len = body_len,
1001310065 },
1001410066 );
10015 gz.astgen.extra.appendSliceAssumeCapacity(body);
10067 astgen.appendBodyWithFixups(body);
1001610068 gz.unstack();
1001710069 }
1001810070
......@@ -10089,6 +10141,7 @@ const GenZir = struct {
1008910141 if (args.ret_gz) |ret_gz|
1009010142 ret_body = ret_gz.instructionsSlice();
1009110143 }
10144 const body_len = astgen.countBodyLenAfterFixups(body);
1009210145
1009310146 if (args.cc_ref != .none or args.lib_name != 0 or
1009410147 args.is_var_args or args.is_test or args.is_extern or
......@@ -10114,13 +10167,13 @@ const GenZir = struct {
1011410167 fancyFnExprExtraLen(section_body, args.section_ref) +
1011510168 fancyFnExprExtraLen(cc_body, args.cc_ref) +
1011610169 fancyFnExprExtraLen(ret_body, ret_ref) +
10117 body.len + src_locs.len +
10170 body_len + src_locs.len +
1011810171 @boolToInt(args.lib_name != 0) +
1011910172 @boolToInt(args.noalias_bits != 0),
1012010173 );
1012110174 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.FuncFancy{
1012210175 .param_block = args.param_block,
10123 .body_len = @intCast(u32, body.len),
10176 .body_len = body_len,
1012410177 .bits = .{
1012510178 .is_var_args = args.is_var_args,
1012610179 .is_inferred_error = args.is_inferred_error,
......@@ -10187,7 +10240,7 @@ const GenZir = struct {
1018710240 astgen.extra.appendAssumeCapacity(args.noalias_bits);
1018810241 }
1018910242
10190 astgen.extra.appendSliceAssumeCapacity(body);
10243 astgen.appendBodyWithFixups(body);
1019110244 astgen.extra.appendSliceAssumeCapacity(src_locs);
1019210245
1019310246 // Order is important when unstacking.
......@@ -10214,9 +10267,9 @@ const GenZir = struct {
1021410267 } else {
1021510268 try astgen.extra.ensureUnusedCapacity(
1021610269 gpa,
10217 @typeInfo(Zir.Inst.Func).Struct.fields.len +
10270 @typeInfo(Zir.Inst.Func).Struct.fields.len + 1 +
1021810271 @maximum(ret_body.len, @boolToInt(ret_ref != .none)) +
10219 body.len + src_locs.len,
10272 body_len + src_locs.len,
1022010273 );
1022110274 const ret_body_len = if (ret_body.len != 0)
1022210275 @intCast(u32, ret_body.len)
......@@ -10226,7 +10279,7 @@ const GenZir = struct {
1022610279 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.Func{
1022710280 .param_block = args.param_block,
1022810281 .ret_body_len = ret_body_len,
10229 .body_len = @intCast(u32, body.len),
10282 .body_len = body_len,
1023010283 });
1023110284 const zir_datas = astgen.instructions.items(.data);
1023210285 if (ret_body.len != 0) {
......@@ -10235,7 +10288,7 @@ const GenZir = struct {
1023510288 } else if (ret_ref != .none) {
1023610289 astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
1023710290 }
10238 astgen.extra.appendSliceAssumeCapacity(body);
10291 astgen.appendBodyWithFixups(body);
1023910292 astgen.extra.appendSliceAssumeCapacity(src_locs);
1024010293
1024110294 // Order is important when unstacking.
......@@ -10593,6 +10646,26 @@ const GenZir = struct {
1059310646 });
1059410647 }
1059510648
10649 fn makeUnTok(
10650 gz: *GenZir,
10651 tag: Zir.Inst.Tag,
10652 operand: Zir.Inst.Ref,
10653 /// Absolute token index. This function does the conversion to Decl offset.
10654 abs_tok_index: Ast.TokenIndex,
10655 ) !Zir.Inst.Index {
10656 const astgen = gz.astgen;
10657 const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len);
10658 assert(operand != .none);
10659 try astgen.instructions.append(astgen.gpa, .{
10660 .tag = tag,
10661 .data = .{ .un_tok = .{
10662 .operand = operand,
10663 .src_tok = gz.tokenIndexToRelative(abs_tok_index),
10664 } },
10665 });
10666 return new_index;
10667 }
10668
1059610669 fn addStrTok(
1059710670 gz: *GenZir,
1059810671 tag: Zir.Inst.Tag,
......@@ -11337,3 +11410,42 @@ fn isInferred(astgen: *AstGen, ref: Zir.Inst.Ref) bool {
1133711410 else => false,
1133811411 };
1133911412}
11413
11414/// Assumes capacity for body has already been added. Needed capacity taking into
11415/// account fixups can be found with `countBodyLenAfterFixups`.
11416fn appendBodyWithFixups(astgen: *AstGen, body: []const Zir.Inst.Index) void {
11417 return appendBodyWithFixupsArrayList(astgen, &astgen.extra, body);
11418}
11419
11420fn appendBodyWithFixupsArrayList(
11421 astgen: *AstGen,
11422 list: *std.ArrayListUnmanaged(u32),
11423 body: []const Zir.Inst.Index,
11424) void {
11425 for (body) |body_inst| {
11426 appendPossiblyRefdBodyInst(astgen, list, body_inst);
11427 }
11428}
11429
11430fn appendPossiblyRefdBodyInst(
11431 astgen: *AstGen,
11432 list: *std.ArrayListUnmanaged(u32),
11433 body_inst: Zir.Inst.Index,
11434) void {
11435 list.appendAssumeCapacity(body_inst);
11436 const kv = astgen.ref_table.fetchRemove(body_inst) orelse return;
11437 const ref_inst = kv.value;
11438 return appendPossiblyRefdBodyInst(astgen, list, ref_inst);
11439}
11440
11441fn countBodyLenAfterFixups(astgen: *AstGen, body: []const Zir.Inst.Index) u32 {
11442 var count = body.len;
11443 for (body) |body_inst| {
11444 var check_inst = body_inst;
11445 while (astgen.ref_table.get(check_inst)) |ref_inst| {
11446 count += 1;
11447 check_inst = ref_inst;
11448 }
11449 }
11450 return @intCast(u32, count);
11451}
src/Sema.zig+12-5
......@@ -771,7 +771,7 @@ fn analyzeBodyInner(
771771 .ptr_type => try sema.zirPtrType(block, inst),
772772 .ptr_type_simple => try sema.zirPtrTypeSimple(block, inst),
773773 .ref => try sema.zirRef(block, inst),
774 .ret_err_value_code => try sema.zirRetErrValueCode(block, inst),
774 .ret_err_value_code => try sema.zirRetErrValueCode(inst),
775775 .shr => try sema.zirShr(block, inst, .shr),
776776 .shr_exact => try sema.zirShr(block, inst, .shr_exact),
777777 .slice_end => try sema.zirSliceEnd(block, inst),
......@@ -9250,10 +9250,17 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
92509250 return sema.analyzeDeclRef(embed_file.owner_decl);
92519251}
92529252
9253fn zirRetErrValueCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
9254 _ = block;
9255 _ = inst;
9256 return sema.fail(block, sema.src, "TODO implement zirRetErrValueCode", .{});
9253fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
9254 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
9255 const err_name = inst_data.get(sema.code);
9256
9257 // Return the error code from the function.
9258 const kv = try sema.mod.getErrorValue(err_name);
9259 const result_inst = try sema.addConstant(
9260 try Type.Tag.error_set_single.create(sema.arena, kv.key),
9261 try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }),
9262 );
9263 return result_inst;
92579264}
92589265
92599266fn zirShl(
src/Zir.zig+12
......@@ -1271,6 +1271,18 @@ pub const Inst = struct {
12711271 };
12721272 }
12731273
1274 pub fn isParam(tag: Tag) bool {
1275 return switch (tag) {
1276 .param,
1277 .param_comptime,
1278 .param_anytype,
1279 .param_anytype_comptime,
1280 => true,
1281
1282 else => false,
1283 };
1284 }
1285
12741286 /// AstGen uses this to find out if `Ref.void_value` should be used in place
12751287 /// of the result of a given instruction. This allows Sema to forego adding
12761288 /// the instruction to the map after analysis.
src/test.zig+13-9
......@@ -490,9 +490,7 @@ fn getTestFileNameParts(name: []const u8) struct {
490490
491491/// Sort test filenames in-place, so that incremental test cases ("foo.0.zig",
492492/// "foo.1.zig", etc.) are contiguous and appear in numerical order.
493fn sortTestFilenames(
494 filenames: [][]const u8,
495) void {
493fn sortTestFilenames(filenames: [][]const u8) void {
496494 const Context = struct {
497495 pub fn lessThan(_: @This(), a: []const u8, b: []const u8) bool {
498496 const a_parts = getTestFileNameParts(a);
......@@ -505,14 +503,20 @@ fn sortTestFilenames(
505503 .eq => switch (std.mem.order(u8, a_parts.file_ext, b_parts.file_ext)) {
506504 .lt => true,
507505 .gt => false,
508 .eq => b: { // a and b differ only in their ".X" part
506 .eq => {
507 // a and b differ only in their ".X" part
509508
510509 // Sort "<base_name>.<file_ext>" before any "<base_name>.X.<file_ext>"
511 if (a_parts.test_index == null) break :b true;
512 if (b_parts.test_index == null) break :b false;
513
514 // Make sure that incremental tests appear in linear order
515 return a_parts.test_index.? < b_parts.test_index.?;
510 if (a_parts.test_index) |a_index| {
511 if (b_parts.test_index) |b_index| {
512 // Make sure that incremental tests appear in linear order
513 return a_index < b_index;
514 } else {
515 return false;
516 }
517 } else {
518 return b_parts.test_index != null;
519 }
516520 },
517521 },
518522 };
src/type.zig+2-2
......@@ -1843,7 +1843,7 @@ pub const Type = extern union {
18431843 if (payload.@"align" != 0 or payload.host_size != 0) {
18441844 try writer.print("align({d}", .{payload.@"align"});
18451845
1846 if (payload.bit_offset != 0) {
1846 if (payload.bit_offset != 0 or payload.host_size != 0) {
18471847 try writer.print(":{d}:{d}", .{ payload.bit_offset, payload.host_size });
18481848 }
18491849 try writer.writeAll(") ");
......@@ -2167,7 +2167,7 @@ pub const Type = extern union {
21672167 if (info.@"align" != 0 or info.host_size != 0) {
21682168 try writer.print("align({d}", .{info.@"align"});
21692169
2170 if (info.bit_offset != 0) {
2170 if (info.bit_offset != 0 or info.host_size != 0) {
21712171 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
21722172 }
21732173 try writer.writeAll(") ");
test/behavior.zig-1
......@@ -27,7 +27,6 @@ test {
2727 _ = @import("behavior/bugs/1025.zig");
2828 _ = @import("behavior/bugs/1076.zig");
2929 _ = @import("behavior/bugs/1111.zig");
30 _ = @import("behavior/bugs/1120.zig");
3130 _ = @import("behavior/bugs/1277.zig");
3231 _ = @import("behavior/bugs/1310.zig");
3332 _ = @import("behavior/bugs/1381.zig");
test/behavior/bugs/1120.zig deleted-25
......@@ -1,25 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3
4const A = packed struct {
5 a: u2,
6 b: u6,
7};
8const B = packed struct {
9 q: u8,
10 a: u2,
11 b: u6,
12};
13test "bug 1120" {
14 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
15
16 var a = A{ .a = 2, .b = 2 };
17 var b = B{ .q = 22, .a = 3, .b = 2 };
18 var t: usize = 0;
19 const ptr = switch (t) {
20 0 => &a.a,
21 1 => &b.a,
22 else => unreachable,
23 };
24 try expect(ptr.* == 2);
25}
test/behavior/bugs/6781.zig+7-2
......@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
12const std = @import("std");
23const assert = std.debug.assert;
34
......@@ -61,9 +62,13 @@ pub const JournalHeader = packed struct {
6162};
6263
6364test "fixed" {
64 if (@import("builtin").zig_backend != .stage1) return error.SkipZigTest; // TODO
65 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
66 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
67 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
68 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
69 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
6570
66 var buffer = [_]u8{0} ** 65536;
71 var buffer align(@alignOf(JournalHeader)) = [_]u8{0} ** 65536;
6772 var entry = std.mem.bytesAsValue(JournalHeader, buffer[0..@sizeOf(JournalHeader)]);
6873 entry.* = .{
6974 .prev_hash_chain_root = 0,
test/behavior/defer.zig+4-1
......@@ -108,7 +108,10 @@ test "mixing normal and error defers" {
108108}
109109
110110test "errdefer with payload" {
111 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
111 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
112 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
113 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
114 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
112115
113116 const S = struct {
114117 fn foo() !i32 {
test/behavior/eval.zig-2
......@@ -1191,8 +1191,6 @@ test "no dependency loop for alignment of self tagged union" {
11911191}
11921192
11931193test "equality of pointers to comptime const" {
1194 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
1195
11961194 const a: i32 = undefined;
11971195 comptime assert(&a == &a);
11981196}
test/cases/compile_errors/incompatible sub-byte fields.zig created+27
......@@ -0,0 +1,27 @@
1const A = packed struct {
2 a: u2,
3 b: u6,
4};
5const B = packed struct {
6 q: u8,
7 a: u2,
8 b: u6,
9};
10export fn entry() void {
11 var a = A{ .a = 2, .b = 2 };
12 var b = B{ .q = 22, .a = 3, .b = 2 };
13 var t: usize = 0;
14 const ptr = switch (t) {
15 0 => &a.a,
16 1 => &b.a,
17 else => unreachable,
18 };
19 if (ptr.* == 2) {
20 @compileError("wrong compile error");
21 }
22}
23// error
24// backend=stage2
25// target=native
26//
27// :14:17: error: incompatible types: '*align(0:0:1) u2' and '*align(2:8:2) u2'