Commit 49be88859d

Andrew Kelley <andrew@ziglang.org>
2021-04-24 05:31:12
AstGen: implement nosuspend expressions
Also implement ZIR error notes
1 parent 9a27134
src/AstGen.zig
@@ -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(
src/Compilation.zig
@@ -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),
                 },
             });
BRANCH_TODO
@@ -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