AstGen: implement nosuspend expressions

Also implement ZIR error notes
This commit is contained in:
Andrew Kelley 2021-04-23 20:31:12 -07:00
parent 9a271347fe
commit 49be88859d
3 changed files with 53 additions and 3 deletions

View File

@ -37,6 +37,9 @@
* when handling decls, catch the error and continue, so that
AstGen can report more than one compile error.
* AstGen: inside a nosuspend block, emit function calls as nosuspend calls
* AstGen: add result location pointers to function calls
const container_name_hash: Scope.NameHash = if (found_pkg) |pkg|
pkg.namespace_hash
else

View File

@ -890,7 +890,25 @@ pub fn nosuspendExpr(
node: ast.Node.Index,
) InnerError!Zir.Inst.Ref {
const astgen = gz.astgen;
return astgen.failNode(node, "TODO AstGen nosuspendExpr", .{});
const gpa = astgen.gpa;
const tree = &astgen.file.tree;
const node_datas = tree.nodes.items(.data);
const body_node = node_datas[node].lhs;
assert(body_node != 0);
if (gz.nosuspend_node != 0) {
return astgen.failNodeNotes(node, "redundant nosuspend block", .{}, &[_]u32{
try astgen.errNoteNode(gz.nosuspend_node, "other nosuspend block here", .{}),
});
}
if (gz.suspend_node != 0) {
return astgen.failNodeNotes(node, "inside a suspend block, nosuspend is implied", .{}, &[_]u32{
try astgen.errNoteNode(gz.suspend_node, "suspend block here", .{}),
});
}
gz.nosuspend_node = node;
const result = try expr(gz, scope, rl, body_node);
gz.nosuspend_node = 0;
return rvalue(gz, scope, rl, result, node);
}
pub fn suspendExpr(

View File

@ -441,8 +441,37 @@ pub const AllErrors = struct {
const item = file.zir.extraData(Zir.Inst.CompileErrors.Item, extra_index);
extra_index = item.end;
var notes: []Message = &[0]Message{};
if (item.data.notes != 0) {
@panic("TODO implement AllErrors for Zir notes");
const block = file.zir.extraData(Zir.Inst.Block, item.data.notes);
const body = file.zir.extra[block.end..][0..block.data.body_len];
notes = try arena.alloc(Message, body.len);
for (notes) |*note, i| {
const note_item = file.zir.extraData(Zir.Inst.CompileErrors.Item, body[i]);
const msg = file.zir.nullTerminatedString(note_item.data.msg);
const byte_offset = blk: {
const token_starts = file.tree.tokens.items(.start);
if (note_item.data.node != 0) {
const main_tokens = file.tree.nodes.items(.main_token);
const main_token = main_tokens[note_item.data.node];
break :blk token_starts[main_token];
}
break :blk token_starts[note_item.data.token] + note_item.data.byte_offset;
};
const loc = std.zig.findLineColumn(source, byte_offset);
note.* = .{
.src = .{
.src_path = try arena.dupe(u8, file.sub_file_path),
.msg = try arena.dupe(u8, msg),
.byte_offset = byte_offset,
.line = @intCast(u32, loc.line),
.column = @intCast(u32, loc.column),
.notes = &.{}, // TODO rework this function to be recursive
.source_line = try arena.dupe(u8, loc.source_line),
},
};
}
}
const msg = file.zir.nullTerminatedString(item.data.msg);
@ -464,7 +493,7 @@ pub const AllErrors = struct {
.byte_offset = byte_offset,
.line = @intCast(u32, loc.line),
.column = @intCast(u32, loc.column),
.notes = &.{}, // TODO
.notes = notes,
.source_line = try arena.dupe(u8, loc.source_line),
},
});