mirror of
https://github.com/ziglang/zig.git
synced 2026-01-16 20:35:17 +00:00
stage2: validate struct/array init ty
This commit is contained in:
parent
6f0601c793
commit
a2533e6fca
@ -1282,6 +1282,7 @@ fn arrayInitExpr(
|
||||
}
|
||||
}
|
||||
const array_type_inst = try typeExpr(gz, scope, array_init.ast.type_expr);
|
||||
_ = try gz.addUnNode(.validate_array_init_ty, array_type_inst, node);
|
||||
const elem_type = try gz.addUnNode(.elem_type, array_type_inst, array_init.ast.type_expr);
|
||||
break :inst .{
|
||||
.array = array_type_inst,
|
||||
@ -1495,8 +1496,10 @@ fn structInitExpr(
|
||||
switch (rl) {
|
||||
.discard => {
|
||||
// TODO if a type expr is given the fields should be validated for that type
|
||||
if (struct_init.ast.type_expr != 0)
|
||||
_ = try typeExpr(gz, scope, struct_init.ast.type_expr);
|
||||
if (struct_init.ast.type_expr != 0) {
|
||||
const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
|
||||
_ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node);
|
||||
}
|
||||
for (struct_init.ast.fields) |field_init| {
|
||||
_ = try expr(gz, scope, .discard, field_init);
|
||||
}
|
||||
@ -1505,6 +1508,7 @@ fn structInitExpr(
|
||||
.ref => {
|
||||
if (struct_init.ast.type_expr != 0) {
|
||||
const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
|
||||
_ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node);
|
||||
return structInitExprRlTy(gz, scope, node, struct_init, ty_inst, .struct_init_ref);
|
||||
} else {
|
||||
return structInitExprRlNone(gz, scope, node, struct_init, .struct_init_anon_ref);
|
||||
@ -1513,6 +1517,7 @@ fn structInitExpr(
|
||||
.none => {
|
||||
if (struct_init.ast.type_expr != 0) {
|
||||
const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
|
||||
_ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node);
|
||||
return structInitExprRlTy(gz, scope, node, struct_init, ty_inst, .struct_init);
|
||||
} else {
|
||||
return structInitExprRlNone(gz, scope, node, struct_init, .struct_init_anon);
|
||||
@ -1523,6 +1528,7 @@ fn structInitExpr(
|
||||
return structInitExprRlTy(gz, scope, node, struct_init, ty_inst, .struct_init);
|
||||
}
|
||||
const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
|
||||
_ = try gz.addUnNode(.validate_struct_init_ty, inner_ty_inst, node);
|
||||
const result = try structInitExprRlTy(gz, scope, node, struct_init, inner_ty_inst, .struct_init);
|
||||
return rvalue(gz, rl, result, node);
|
||||
},
|
||||
@ -1573,6 +1579,7 @@ fn structInitExprRlPtr(
|
||||
return structInitExprRlPtrInner(gz, scope, node, struct_init, base_ptr);
|
||||
}
|
||||
const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr);
|
||||
_ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node);
|
||||
|
||||
var as_scope = try gz.makeCoercionScope(scope, ty_inst, result_ptr);
|
||||
defer as_scope.unstack();
|
||||
@ -2334,6 +2341,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
|
||||
.closure_capture,
|
||||
.memcpy,
|
||||
.memset,
|
||||
.validate_array_init_ty,
|
||||
.validate_struct_init_ty,
|
||||
=> break :b true,
|
||||
}
|
||||
} else switch (maybe_unused_result) {
|
||||
|
||||
61
src/Sema.zig
61
src/Sema.zig
@ -872,6 +872,16 @@ fn analyzeBodyInner(
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.validate_array_init_ty => {
|
||||
try sema.validateArrayInitTy(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.validate_struct_init_ty => {
|
||||
try sema.validateStructInitTy(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.validate_struct_init => {
|
||||
try sema.zirValidateStructInit(block, inst, false);
|
||||
i += 1;
|
||||
@ -1341,6 +1351,14 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, opt
|
||||
return sema.fail(block, src, "expected optional type, found {}", .{optional_ty});
|
||||
}
|
||||
|
||||
fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
|
||||
return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{ty});
|
||||
}
|
||||
|
||||
fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError {
|
||||
return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{ty});
|
||||
}
|
||||
|
||||
fn failWithErrorSetCodeMissing(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
@ -2614,9 +2632,7 @@ fn zirArrayBasePtr(
|
||||
.Struct => if (elem_ty.isTuple()) return base_ptr,
|
||||
else => {},
|
||||
}
|
||||
return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{
|
||||
sema.typeOf(start_ptr).childType(),
|
||||
});
|
||||
return sema.failWithArrayInitNotSupported(block, src, sema.typeOf(start_ptr).childType());
|
||||
}
|
||||
|
||||
fn zirFieldBasePtr(
|
||||
@ -2640,9 +2656,40 @@ fn zirFieldBasePtr(
|
||||
.Struct, .Union => return base_ptr,
|
||||
else => {},
|
||||
}
|
||||
return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{
|
||||
sema.typeOf(start_ptr).childType(),
|
||||
});
|
||||
return sema.failWithStructInitNotSupported(block, src, sema.typeOf(start_ptr).childType());
|
||||
}
|
||||
|
||||
fn validateArrayInitTy(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
inst: Zir.Inst.Index,
|
||||
) CompileError!void {
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
|
||||
const src = inst_data.src();
|
||||
const ty = try sema.resolveType(block, src, inst_data.operand);
|
||||
|
||||
switch (ty.zigTypeTag()) {
|
||||
.Array, .Vector => return,
|
||||
.Struct => if (ty.isTuple()) return,
|
||||
else => {},
|
||||
}
|
||||
return sema.failWithArrayInitNotSupported(block, src, ty);
|
||||
}
|
||||
|
||||
fn validateStructInitTy(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
inst: Zir.Inst.Index,
|
||||
) CompileError!void {
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
|
||||
const src = inst_data.src();
|
||||
const ty = try sema.resolveType(block, src, inst_data.operand);
|
||||
|
||||
switch (ty.zigTypeTag()) {
|
||||
.Struct, .Union => return,
|
||||
else => {},
|
||||
}
|
||||
return sema.failWithStructInitNotSupported(block, src, ty);
|
||||
}
|
||||
|
||||
fn zirValidateStructInit(
|
||||
@ -10815,7 +10862,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
|
||||
.Struct => return structInitEmpty(sema, block, obj_ty, src, src),
|
||||
.Array => return arrayInitEmpty(sema, obj_ty),
|
||||
.Void => return sema.addConstant(obj_ty, Value.void),
|
||||
else => unreachable,
|
||||
else => return sema.failWithArrayInitNotSupported(block, src, obj_ty),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
src/Zir.zig
10
src/Zir.zig
@ -655,6 +655,12 @@ pub const Inst = struct {
|
||||
/// *?S returns *S
|
||||
/// Uses the `un_node` field.
|
||||
field_base_ptr,
|
||||
/// Checks that the type supports array init syntax.
|
||||
/// Uses the `un_node` field.
|
||||
validate_array_init_ty,
|
||||
/// Checks that the type supports struct init syntax.
|
||||
/// Uses the `un_node` field.
|
||||
validate_struct_init_ty,
|
||||
/// Given a set of `field_ptr` instructions, assumes they are all part of a struct
|
||||
/// initialization expression, and emits compile errors for duplicate fields
|
||||
/// as well as missing fields, if applicable.
|
||||
@ -1101,6 +1107,8 @@ pub const Inst = struct {
|
||||
.switch_cond_ref,
|
||||
.array_base_ptr,
|
||||
.field_base_ptr,
|
||||
.validate_array_init_ty,
|
||||
.validate_struct_init_ty,
|
||||
.validate_struct_init,
|
||||
.validate_struct_init_comptime,
|
||||
.validate_array_init,
|
||||
@ -1356,6 +1364,8 @@ pub const Inst = struct {
|
||||
.switch_capture_multi_ref = .switch_capture,
|
||||
.array_base_ptr = .un_node,
|
||||
.field_base_ptr = .un_node,
|
||||
.validate_array_init_ty = .un_node,
|
||||
.validate_struct_init_ty = .un_node,
|
||||
.validate_struct_init = .pl_node,
|
||||
.validate_struct_init_comptime = .pl_node,
|
||||
.validate_array_init = .pl_node,
|
||||
|
||||
@ -237,6 +237,8 @@ const Writer = struct {
|
||||
.switch_cond_ref,
|
||||
.array_base_ptr,
|
||||
.field_base_ptr,
|
||||
.validate_array_init_ty,
|
||||
.validate_struct_init_ty,
|
||||
=> try self.writeUnNode(stream, inst),
|
||||
|
||||
.ref,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user