From 13b2f1e90ba9e373c655fc881836209c4fa381fa Mon Sep 17 00:00:00 2001 From: Vexu Date: Sun, 16 Aug 2020 21:51:05 +0300 Subject: [PATCH] address review feedback --- src-self-hosted/Module.zig | 1 - src-self-hosted/astgen.zig | 25 ++++++++++++------------- src-self-hosted/codegen.zig | 4 ++-- src-self-hosted/type.zig | 28 +++++++++++++++++++++++++--- src-self-hosted/zir_sema.zig | 3 +-- 5 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig index 2584066499..8eabe97c31 100644 --- a/src-self-hosted/Module.zig +++ b/src-self-hosted/Module.zig @@ -2433,7 +2433,6 @@ fn wrapOptional(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*In return self.constInst(scope, inst.src, .{ .ty = dest_type, .val = val }); } - // TODO how do we get the result location const b = try self.requireRuntimeBlock(scope, inst.src); return self.addUnOp(b, inst.src, dest_type, .wrap_optional, inst); } diff --git a/src-self-hosted/astgen.zig b/src-self-hosted/astgen.zig index 5335504ed2..2c772f3887 100644 --- a/src-self-hosted/astgen.zig +++ b/src-self-hosted/astgen.zig @@ -453,8 +453,6 @@ fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerErr } fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { - const tree = scope.tree(); - const src = tree.token_locs[node.op_token].start; return expr(mod, scope, .lvalue, node.rhs); } @@ -490,8 +488,6 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir .single_const_ptr_type, child_type); } - const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs); - var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, "kw_args").field_type = .{}; kw_args.@"allowzero" = node.ptr_info.allowzero_token != null; if (node.ptr_info.align_info) |some| { @@ -504,7 +500,12 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir kw_args.@"const" = node.ptr_info.const_token != null; kw_args.@"volatile" = node.ptr_info.volatile_token != null; if (node.ptr_info.sentinel) |some| { - kw_args.sentinel = try expr(mod, scope, .{ .ty = child_type }, some); + kw_args.sentinel = try expr(mod, scope, .none, some); + } + + const child_type = try expr(mod, scope, .{ .ty = meta_type }, node.rhs); + if (kw_args.sentinel) |some| { + kw_args.sentinel = try addZIRBinOp(mod, scope, some.src, .as, child_type, some); } return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args); @@ -629,7 +630,9 @@ const CondKind = union(enum) { const payload = payload_node.?.castTag(.PointerPayload).?; const is_ptr = payload.ptr_token != null; const ident_node = payload.value_symbol.castTag(.Identifier).?; - const ident_name = try identifierTokenString(mod, &then_scope.base, ident_node.token); + + // This intentionally does not support @"_" syntax. + const ident_name = then_scope.base.tree().tokenSlice(ident_node.token); if (mem.eql(u8, ident_name, "_")) { if (is_ptr) return mod.failTok(&then_scope.base, payload.ptr_token.?, "pointer modifier invalid on discard", .{}); @@ -646,7 +649,9 @@ const CondKind = union(enum) { const payload = payload_node.?.castTag(.Payload).?; const ident_node = payload.error_symbol.castTag(.Identifier).?; - const ident_name = try identifierTokenString(mod, &else_scope.base, ident_node.token); + + // This intentionally does not support @"_" syntax. + const ident_name = else_scope.base.tree().tokenSlice(ident_node.token); if (mem.eql(u8, ident_name, "_")) { return &else_scope.base; } @@ -660,9 +665,6 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn if (if_node.payload) |_| cond_kind = .{ .optional = null }; if (if_node.@"else") |else_node| { if (else_node.payload) |payload| { - if (cond_kind != .optional) { - return mod.failNode(scope, payload, "else payload invalid on bool conditions", .{}); - } cond_kind = .{ .err_union = null }; } } @@ -760,9 +762,6 @@ fn whileExpr(mod: *Module, scope: *Scope, rl: ResultLoc, while_node: *ast.Node.W if (while_node.payload) |_| cond_kind = .{ .optional = null }; if (while_node.@"else") |else_node| { if (else_node.payload) |payload| { - if (cond_kind != .optional) { - return mod.failNode(scope, payload, "else payload invalid on bool conditions", .{}); - } cond_kind = .{ .err_union = null }; } } diff --git a/src-self-hosted/codegen.zig b/src-self-hosted/codegen.zig index d37145a275..f49d3b41fd 100644 --- a/src-self-hosted/codegen.zig +++ b/src-self-hosted/codegen.zig @@ -2052,7 +2052,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { return mcv; } - fn genTypedValue(self: *Self, src: usize, typed_value: TypedValue) error{ CodegenFail, OutOfMemory }!MCValue { + fn genTypedValue(self: *Self, src: usize, typed_value: TypedValue) InnerError!MCValue { if (typed_value.val.isUndef()) return MCValue{ .undef = {} }; const ptr_bits = self.target.cpu.arch.ptrBitWidth(); @@ -2199,7 +2199,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { }; } - fn fail(self: *Self, src: usize, comptime format: []const u8, args: anytype) error{ CodegenFail, OutOfMemory } { + fn fail(self: *Self, src: usize, comptime format: []const u8, args: anytype) InnerError { @setCold(true); assert(self.err_msg == null); self.err_msg = try ErrorMsg.create(self.bin_file.base.allocator, src, format, args); diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig index cc3f665c4c..faba784f90 100644 --- a/src-self-hosted/type.zig +++ b/src-self-hosted/type.zig @@ -362,7 +362,7 @@ pub const Type = extern union { .single_mut_pointer, .optional_single_mut_pointer, .optional_single_const_pointer, - => return self.copyPayloadSingleField(allocator, Payload.Pointer, "pointee_type"), + => return self.copyPayloadSingleField(allocator, Payload.Pointer, "pointee_type"), } } @@ -1086,14 +1086,14 @@ pub const Type = extern union { .optional_single_mut_pointer => { buf.* = .{ .base = .{ .tag = .single_mut_pointer }, - .pointee_type = self.castPointer().?.pointee_type + .pointee_type = self.castPointer().?.pointee_type, }; return Type.initPayload(&buf.base); }, .optional_single_const_pointer => { buf.* = .{ .base = .{ .tag = .single_const_pointer }, - .pointee_type = self.castPointer().?.pointee_type + .pointee_type = self.castPointer().?.pointee_type, }; return Type.initPayload(&buf.base); }, @@ -1101,6 +1101,28 @@ pub const Type = extern union { }; } + /// Asserts that the type is an optional. + /// Same as `optionalChild` but allocates the buffer if needed. + pub fn optionalChildAlloc(self: Type, allocator: *Allocator) !Type { + return switch (self.tag()) { + .optional => self.cast(Payload.Optional).?.child_type, + .optional_single_mut_pointer, .optional_single_const_pointer => { + const payload = try allocator.create(Payload.Pointer); + payload.* = .{ + .base = .{ + .tag = if (self.tag() == .optional_single_const_pointer) + .single_const_pointer + else + .single_mut_pointer, + }, + .pointee_type = self.castPointer().?.pointee_type, + }; + return Type.initPayload(&payload.base); + }, + else => unreachable, + }; + } + /// Asserts the type is an array or vector. pub fn arrayLen(self: Type) u64 { return switch (self.tag()) { diff --git a/src-self-hosted/zir_sema.zig b/src-self-hosted/zir_sema.zig index 362dbe7909..31ffb2cc0d 100644 --- a/src-self-hosted/zir_sema.zig +++ b/src-self-hosted/zir_sema.zig @@ -710,8 +710,7 @@ fn analyzeInstUnwrapOptional(mod: *Module, scope: *Scope, unwrap: *zir.Inst.UnOp return mod.fail(scope, unwrap.base.src, "expected optional type, found {}", .{operand.ty.elemType()}); } - var buf: Type.Payload.Pointer = undefined; - const child_type = try operand.ty.elemType().optionalChild(&buf).copy(scope.arena()); + const child_type = try operand.ty.elemType().optionalChildAlloc(scope.arena()); const child_pointer = try mod.singlePtrType(scope, unwrap.base.src, operand.ty.isConstPtr(), child_type); if (operand.value()) |val| {