Commit 13b2f1e90b
Changed files (5)
src-self-hosted
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 };
}
}
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);
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);
}
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()) {
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| {