| author | |
| committer | |
| log | 273da9efd9238e20da1299789537b00de2f0ebd8 |
| tree | 54905594f55be9fd19a179ab1bcaeb1900d02bc1 |
| parent | a30d283981ae31ed0212ef153f086e07daeffe65 |
when an inferred alloc is passed as the result pointer of a block.4 files changed, 69 insertions(+), 10 deletions(-)
src/AstGen.zig+30-1| ... | ... | @@ -1360,6 +1360,12 @@ fn arrayInitExpr( |
| 1360 | 1360 | } |
| 1361 | 1361 | }, |
| 1362 | 1362 | .block_ptr => |block_gz| { |
| 1363 | // This condition is here for the same reason as the above condition in `inferred_ptr`. | |
| 1364 | // See corresponding logic in structInitExpr. | |
| 1365 | if (types.array == .none and astgen.isInferred(block_gz.rl_ptr)) { | |
| 1366 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); | |
| 1367 | return rvalue(gz, rl, result, node); | |
| 1368 | } | |
| 1363 | 1369 | return arrayInitExprRlPtr(gz, scope, rl, node, block_gz.rl_ptr, array_init.ast.elements, types.array); |
| 1364 | 1370 | }, |
| 1365 | 1371 | } |
| ... | ... | @@ -1604,7 +1610,16 @@ fn structInitExpr( |
| 1604 | 1610 | return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_inst); |
| 1605 | 1611 | } |
| 1606 | 1612 | }, |
| 1607 | .block_ptr => |block_gz| return structInitExprRlPtr(gz, scope, rl, node, struct_init, block_gz.rl_ptr), | |
| 1613 | .block_ptr => |block_gz| { | |
| 1614 | // This condition is here for the same reason as the above condition in `inferred_ptr`. | |
| 1615 | // See corresponding logic in arrayInitExpr. | |
| 1616 | if (struct_init.ast.type_expr == 0 and astgen.isInferred(block_gz.rl_ptr)) { | |
| 1617 | const result = try structInitExprRlNone(gz, scope, node, struct_init, .struct_init_anon); | |
| 1618 | return rvalue(gz, rl, result, node); | |
| 1619 | } | |
| 1620 | ||
| 1621 | return structInitExprRlPtr(gz, scope, rl, node, struct_init, block_gz.rl_ptr); | |
| 1622 | }, | |
| 1608 | 1623 | } |
| 1609 | 1624 | } |
| 1610 | 1625 | |
| ... | ... | @@ -10938,3 +10953,17 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast. |
| 10938 | 10953 | } |
| 10939 | 10954 | return decl_count; |
| 10940 | 10955 | } |
| 10956 | ||
| 10957 | fn isInferred(astgen: *AstGen, ref: Zir.Inst.Ref) bool { | |
| 10958 | const inst = refToIndex(ref) orelse return false; | |
| 10959 | const zir_tags = astgen.instructions.items(.tag); | |
| 10960 | return switch (zir_tags[inst]) { | |
| 10961 | .alloc_inferred, | |
| 10962 | .alloc_inferred_mut, | |
| 10963 | .alloc_inferred_comptime, | |
| 10964 | .alloc_inferred_comptime_mut, | |
| 10965 | => true, | |
| 10966 | ||
| 10967 | else => false, | |
| 10968 | }; | |
| 10969 | } |
src/Zir.zig+1-1| ... | ... | @@ -516,7 +516,7 @@ pub const Inst = struct { |
| 516 | 516 | /// Same as `store` except provides a source location. |
| 517 | 517 | /// Uses the `pl_node` union field. Payload is `Bin`. |
| 518 | 518 | store_node, |
| 519 | /// This instruction is not really supposed to be emitted from AstGen; nevetheless it | |
| 519 | /// This instruction is not really supposed to be emitted from AstGen; nevertheless it | |
| 520 | 520 | /// is sometimes emitted due to deficiencies in AstGen. When Sema sees this instruction, |
| 521 | 521 | /// it must clean up after AstGen's mess by looking at various context clues and |
| 522 | 522 | /// then treating it as one of the following: |
test/behavior/bugs/5474.zig+6-8| ... | ... | @@ -49,19 +49,17 @@ fn constant() !void { |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | test "pointer-to-array constness for zero-size elements, var" { |
| 52 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 53 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 54 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 55 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 52 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 53 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 54 | ||
| 56 | 55 | try mutable(); |
| 57 | 56 | comptime try mutable(); |
| 58 | 57 | } |
| 59 | 58 | |
| 60 | 59 | test "pointer-to-array constness for zero-size elements, const" { |
| 61 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | |
| 62 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | |
| 63 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | |
| 64 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 60 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 61 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 62 | ||
| 65 | 63 | try constant(); |
| 66 | 64 | comptime try constant(); |
| 67 | 65 | } |
test/behavior/tuple.zig+32| ... | ... | @@ -165,3 +165,35 @@ test "array-like initializer for tuple types" { |
| 165 | 165 | try S.doTheTest(); |
| 166 | 166 | comptime try S.doTheTest(); |
| 167 | 167 | } |
| 168 | ||
| 169 | test "anon struct as the result from a labeled block" { | |
| 170 | const S = struct { | |
| 171 | fn doTheTest() !void { | |
| 172 | const precomputed = comptime blk: { | |
| 173 | var x: i32 = 1234; | |
| 174 | break :blk .{ | |
| 175 | .x = x, | |
| 176 | }; | |
| 177 | }; | |
| 178 | try expect(precomputed.x == 1234); | |
| 179 | } | |
| 180 | }; | |
| 181 | ||
| 182 | try S.doTheTest(); | |
| 183 | comptime try S.doTheTest(); | |
| 184 | } | |
| 185 | ||
| 186 | test "tuple as the result from a labeled block" { | |
| 187 | const S = struct { | |
| 188 | fn doTheTest() !void { | |
| 189 | const precomputed = comptime blk: { | |
| 190 | var x: i32 = 1234; | |
| 191 | break :blk .{x}; | |
| 192 | }; | |
| 193 | try expect(precomputed[0] == 1234); | |
| 194 | } | |
| 195 | }; | |
| 196 | ||
| 197 | try S.doTheTest(); | |
| 198 | comptime try S.doTheTest(); | |
| 199 | } |