authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-19 22:31:24+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-20 02:11:06+02:00
loga2533e6fca0f28aa64717d8e4c13fe6a780b8b15
tree3509a8742dcf45ff99d6d370347bbc4ac08643d7
parent6f0601c79336d688c80a3b8592cf758f3c94a636

stage2: validate struct/array init ty


4 files changed, 77 insertions(+), 9 deletions(-)

src/AstGen.zig+11-2
...@@ -1282,6 +1282,7 @@ fn arrayInitExpr(...@@ -1282,6 +1282,7 @@ fn arrayInitExpr(
1282 }1282 }
1283 }1283 }
1284 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);1284 const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);
1285 _ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, node);
1285 const elem_type = try gz.addUnNode(.elem_type, array_type_inst, array_init.ast.type_expr);1286 const elem_type = try gz.addUnNode(.elem_type, array_type_inst, array_init.ast.type_expr);
1286 break :inst .{1287 break :inst .{
1287 .array = array_type_inst,1288 .array = array_type_inst,
...@@ -1495,8 +1496,10 @@ fn structInitExpr(...@@ -1495,8 +1496,10 @@ fn structInitExpr(
1495 switch (rl) {1496 switch (rl) {
1496 .discard => {1497 .discard => {
1497 // TODO if a type expr is given the fields should be validated for that type1498 // TODO if a type expr is given the fields should be validated for that type
1498 if (struct_init.ast.type_expr != 0)1499 if (struct_init.ast.type_expr != 0) {
1499 _ = try typeExpr(gz, scope, struct_init.ast.type_expr);1500 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1501 _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node);
1502 }
1500 for (struct_init.ast.fields) |field_init| {1503 for (struct_init.ast.fields) |field_init| {
1501 _ = try expr(gz, scope, .discard, field_init);1504 _ = try expr(gz, scope, .discard, field_init);
1502 }1505 }
...@@ -1505,6 +1508,7 @@ fn structInitExpr(...@@ -1505,6 +1508,7 @@ fn structInitExpr(
1505 .ref => {1508 .ref => {
1506 if (struct_init.ast.type_expr != 0) {1509 if (struct_init.ast.type_expr != 0) {
1507 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);1510 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1511 _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node);
1508 return structInitExprRlTy(gz, scope, node, struct_init, ty_inst, .struct_init_ref);1512 return structInitExprRlTy(gz, scope, node, struct_init, ty_inst, .struct_init_ref);
1509 } else {1513 } else {
1510 return structInitExprRlNone(gz, scope, node, struct_init, .struct_init_anon_ref);1514 return structInitExprRlNone(gz, scope, node, struct_init, .struct_init_anon_ref);
...@@ -1513,6 +1517,7 @@ fn structInitExpr(...@@ -1513,6 +1517,7 @@ fn structInitExpr(
1513 .none => {1517 .none => {
1514 if (struct_init.ast.type_expr != 0) {1518 if (struct_init.ast.type_expr != 0) {
1515 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);1519 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1520 _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node);
1516 return structInitExprRlTy(gz, scope, node, struct_init, ty_inst, .struct_init);1521 return structInitExprRlTy(gz, scope, node, struct_init, ty_inst, .struct_init);
1517 } else {1522 } else {
1518 return structInitExprRlNone(gz, scope, node, struct_init, .struct_init_anon);1523 return structInitExprRlNone(gz, scope, node, struct_init, .struct_init_anon);
...@@ -1523,6 +1528,7 @@ fn structInitExpr(...@@ -1523,6 +1528,7 @@ fn structInitExpr(
1523 return structInitExprRlTy(gz, scope, node, struct_init, ty_inst, .struct_init);1528 return structInitExprRlTy(gz, scope, node, struct_init, ty_inst, .struct_init);
1524 }1529 }
1525 const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);1530 const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1531 _ = try gz.addUnNode(.validate_struct_init_ty, inner_ty_inst, node);
1526 const result = try structInitExprRlTy(gz, scope, node, struct_init, inner_ty_inst, .struct_init);1532 const result = try structInitExprRlTy(gz, scope, node, struct_init, inner_ty_inst, .struct_init);
1527 return rvalue(gz, rl, result, node);1533 return rvalue(gz, rl, result, node);
1528 },1534 },
...@@ -1573,6 +1579,7 @@ fn structInitExprRlPtr(...@@ -1573,6 +1579,7 @@ fn structInitExprRlPtr(
1573 return structInitExprRlPtrInner(gz, scope, node, struct_init, base_ptr);1579 return structInitExprRlPtrInner(gz, scope, node, struct_init, base_ptr);
1574 }1580 }
1575 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);1581 const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
1582 _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node);
15761583
1577 var as_scope = try gz.makeCoercionScope(scope, ty_inst, result_ptr);1584 var as_scope = try gz.makeCoercionScope(scope, ty_inst, result_ptr);
1578 defer as_scope.unstack();1585 defer as_scope.unstack();
...@@ -2334,6 +2341,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner...@@ -2334,6 +2341,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
2334 .closure_capture,2341 .closure_capture,
2335 .memcpy,2342 .memcpy,
2336 .memset,2343 .memset,
2344 .validate_array_init_ty,
2345 .validate_struct_init_ty,
2337 => break :b true,2346 => break :b true,
2338 }2347 }
2339 } else switch (maybe_unused_result) {2348 } else switch (maybe_unused_result) {
src/Sema.zig+54-7
...@@ -872,6 +872,16 @@ fn analyzeBodyInner(...@@ -872,6 +872,16 @@ fn analyzeBodyInner(
872 i += 1;872 i += 1;
873 continue;873 continue;
874 },874 },
875 .validate_array_init_ty => {
876 try sema.validateArrayInitTy(block, inst);
877 i += 1;
878 continue;
879 },
880 .validate_struct_init_ty => {
881 try sema.validateStructInitTy(block, inst);
882 i += 1;
883 continue;
884 },
875 .validate_struct_init => {885 .validate_struct_init => {
876 try sema.zirValidateStructInit(block, inst, false);886 try sema.zirValidateStructInit(block, inst, false);
877 i += 1;887 i += 1;
...@@ -1341,6 +1351,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, opt...@@ -1341,6 +1351,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, opt
1341 return sema.fail(block, src, "expected optional type, found {}", .{optional_ty});1351 return sema.fail(block, src, "expected optional type, found {}", .{optional_ty});
1342}1352}
13431353
1354fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
1355 return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{ty});
1356}
1357
1358fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
1359 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{ty});
1360}
1361
1344fn failWithErrorSetCodeMissing(1362fn failWithErrorSetCodeMissing(
1345 sema: *Sema,1363 sema: *Sema,
1346 block: *Block,1364 block: *Block,
...@@ -2614,9 +2632,7 @@ fn zirArrayBasePtr(...@@ -2614,9 +2632,7 @@ fn zirArrayBasePtr(
2614 .Struct => if (elem_ty.isTuple()) return base_ptr,2632 .Struct => if (elem_ty.isTuple()) return base_ptr,
2615 else => {},2633 else => {},
2616 }2634 }
2617 return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{2635 return sema.failWithArrayInitNotSupported(block, src, sema.typeOf(start_ptr).childType());
2618 sema.typeOf(start_ptr).childType(),
2619 });
2620}2636}
26212637
2622fn zirFieldBasePtr(2638fn zirFieldBasePtr(
...@@ -2640,9 +2656,40 @@ fn zirFieldBasePtr(...@@ -2640,9 +2656,40 @@ fn zirFieldBasePtr(
2640 .Struct, .Union => return base_ptr,2656 .Struct, .Union => return base_ptr,
2641 else => {},2657 else => {},
2642 }2658 }
2643 return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{2659 return sema.failWithStructInitNotSupported(block, src, sema.typeOf(start_ptr).childType());
2644 sema.typeOf(start_ptr).childType(),2660}
2645 });2661
2662fn validateArrayInitTy(
2663 sema: *Sema,
2664 block: *Block,
2665 inst: Zir.Inst.Index,
2666) CompileError!void {
2667 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
2668 const src = inst_data.src();
2669 const ty = try sema.resolveType(block, src, inst_data.operand);
2670
2671 switch (ty.zigTypeTag()) {
2672 .Array, .Vector => return,
2673 .Struct => if (ty.isTuple()) return,
2674 else => {},
2675 }
2676 return sema.failWithArrayInitNotSupported(block, src, ty);
2677}
2678
2679fn validateStructInitTy(
2680 sema: *Sema,
2681 block: *Block,
2682 inst: Zir.Inst.Index,
2683) CompileError!void {
2684 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
2685 const src = inst_data.src();
2686 const ty = try sema.resolveType(block, src, inst_data.operand);
2687
2688 switch (ty.zigTypeTag()) {
2689 .Struct, .Union => return,
2690 else => {},
2691 }
2692 return sema.failWithStructInitNotSupported(block, src, ty);
2646}2693}
26472694
2648fn zirValidateStructInit(2695fn zirValidateStructInit(
...@@ -10815,7 +10862,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -10815,7 +10862,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
10815 .Struct => return structInitEmpty(sema, block, obj_ty, src, src),10862 .Struct => return structInitEmpty(sema, block, obj_ty, src, src),
10816 .Array => return arrayInitEmpty(sema, obj_ty),10863 .Array => return arrayInitEmpty(sema, obj_ty),
10817 .Void => return sema.addConstant(obj_ty, Value.void),10864 .Void => return sema.addConstant(obj_ty, Value.void),
10818 else => unreachable,10865 else => return sema.failWithArrayInitNotSupported(block, src, obj_ty),
10819 }10866 }
10820}10867}
1082110868
src/Zir.zig+10
...@@ -655,6 +655,12 @@ pub const Inst = struct {...@@ -655,6 +655,12 @@ pub const Inst = struct {
655 /// *?S returns *S655 /// *?S returns *S
656 /// Uses the `un_node` field.656 /// Uses the `un_node` field.
657 field_base_ptr,657 field_base_ptr,
658 /// Checks that the type supports array init syntax.
659 /// Uses the `un_node` field.
660 validate_array_init_ty,
661 /// Checks that the type supports struct init syntax.
662 /// Uses the `un_node` field.
663 validate_struct_init_ty,
658 /// Given a set of `field_ptr` instructions, assumes they are all part of a struct664 /// Given a set of `field_ptr` instructions, assumes they are all part of a struct
659 /// initialization expression, and emits compile errors for duplicate fields665 /// initialization expression, and emits compile errors for duplicate fields
660 /// as well as missing fields, if applicable.666 /// as well as missing fields, if applicable.
...@@ -1101,6 +1107,8 @@ pub const Inst = struct {...@@ -1101,6 +1107,8 @@ pub const Inst = struct {
1101 .switch_cond_ref,1107 .switch_cond_ref,
1102 .array_base_ptr,1108 .array_base_ptr,
1103 .field_base_ptr,1109 .field_base_ptr,
1110 .validate_array_init_ty,
1111 .validate_struct_init_ty,
1104 .validate_struct_init,1112 .validate_struct_init,
1105 .validate_struct_init_comptime,1113 .validate_struct_init_comptime,
1106 .validate_array_init,1114 .validate_array_init,
...@@ -1356,6 +1364,8 @@ pub const Inst = struct {...@@ -1356,6 +1364,8 @@ pub const Inst = struct {
1356 .switch_capture_multi_ref = .switch_capture,1364 .switch_capture_multi_ref = .switch_capture,
1357 .array_base_ptr = .un_node,1365 .array_base_ptr = .un_node,
1358 .field_base_ptr = .un_node,1366 .field_base_ptr = .un_node,
1367 .validate_array_init_ty = .un_node,
1368 .validate_struct_init_ty = .un_node,
1359 .validate_struct_init = .pl_node,1369 .validate_struct_init = .pl_node,
1360 .validate_struct_init_comptime = .pl_node,1370 .validate_struct_init_comptime = .pl_node,
1361 .validate_array_init = .pl_node,1371 .validate_array_init = .pl_node,
src/print_zir.zig+2
...@@ -237,6 +237,8 @@ const Writer = struct {...@@ -237,6 +237,8 @@ const Writer = struct {
237 .switch_cond_ref,237 .switch_cond_ref,
238 .array_base_ptr,238 .array_base_ptr,
239 .field_base_ptr,239 .field_base_ptr,
240 .validate_array_init_ty,
241 .validate_struct_init_ty,
240 => try self.writeUnNode(stream, inst),242 => try self.writeUnNode(stream, inst),
241243
242 .ref,244 .ref,