diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-01-02 14:28:03 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-01-02 19:11:56 -0700 |
| commit | 50a530196ca4e91b387f9937475dd8891edb3f4f (patch) | |
| tree | c90e57e1484a4c6fed1ae7922f761a9bdd6e7970 /src/Module.zig | |
| parent | 006e7f68056af62ae7713d7ef228841d11874735 (diff) | |
| download | zig-50a530196ca4e91b387f9937475dd8891edb3f4f.tar.gz zig-50a530196ca4e91b387f9937475dd8891edb3f4f.zip | |
stage2: fix handling compile error in inline fn call
* scopes properly inherit inlining information
* compile errors of inline function calls are properly attached to the
caller rather than the callee.
- added a test case for this
* --watch still opens a repl if compile errors happen.
Diffstat (limited to 'src/Module.zig')
| -rw-r--r-- | src/Module.zig | 71 |
1 files changed, 43 insertions, 28 deletions
diff --git a/src/Module.zig b/src/Module.zig index be6ca0df63..8acc485079 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -759,33 +759,33 @@ pub const Scope = struct { instructions: ArrayListUnmanaged(*Inst), /// Points to the arena allocator of DeclAnalysis arena: *Allocator, - label: Label = Label.none, + label: ?Label = null, + inlining: ?Inlining, is_comptime: bool, - pub const Label = union(enum) { - none, - /// This `Block` maps a block ZIR instruction to the corresponding - /// TZIR instruction for break instruction analysis. - breaking: struct { - zir_block: *zir.Inst.Block, - merges: Merges, - }, - /// This `Block` indicates that an inline function call is happening - /// and return instructions should be analyzed as a break instruction - /// to this TZIR block instruction. - inlining: struct { - /// We use this to count from 0 so that arg instructions know - /// which parameter index they are, without having to store - /// a parameter index with each arg instruction. - param_index: usize, - casted_args: []*Inst, - merges: Merges, - }, + /// This `Block` maps a block ZIR instruction to the corresponding + /// TZIR instruction for break instruction analysis. + pub const Label = struct { + zir_block: *zir.Inst.Block, + merges: Merges, + }; - pub const Merges = struct { - results: ArrayListUnmanaged(*Inst), - block_inst: *Inst.Block, - }; + /// This `Block` indicates that an inline function call is happening + /// and return instructions should be analyzed as a break instruction + /// to this TZIR block instruction. + pub const Inlining = struct { + caller: ?*Fn, + /// We use this to count from 0 so that arg instructions know + /// which parameter index they are, without having to store + /// a parameter index with each arg instruction. + param_index: usize, + casted_args: []*Inst, + merges: Merges, + }; + + pub const Merges = struct { + results: ArrayListUnmanaged(*Inst), + block_inst: *Inst.Block, }; /// For debugging purposes. @@ -1093,6 +1093,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { .decl = decl, .instructions = .{}, .arena = &decl_arena.allocator, + .inlining = null, .is_comptime = false, }; defer block_scope.instructions.deinit(self.gpa); @@ -1281,6 +1282,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { .decl = decl, .instructions = .{}, .arena = &decl_arena.allocator, + .inlining = null, .is_comptime = true, }; defer block_scope.instructions.deinit(self.gpa); @@ -1346,6 +1348,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { .decl = decl, .instructions = .{}, .arena = &gen_scope_arena.allocator, + .inlining = null, .is_comptime = true, }; defer inner_block.instructions.deinit(self.gpa); @@ -1466,6 +1469,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { .decl = decl, .instructions = .{}, .arena = &analysis_arena.allocator, + .inlining = null, .is_comptime = true, }; defer block_scope.instructions.deinit(self.gpa); @@ -1843,6 +1847,7 @@ pub fn analyzeFnBody(self: *Module, decl: *Decl, func: *Fn) !void { .decl = decl, .instructions = .{}, .arena = &arena.allocator, + .inlining = null, .is_comptime = false, }; defer inner_block.instructions.deinit(self.gpa); @@ -3050,11 +3055,20 @@ fn failWithOwnedErrorMsg(self: *Module, scope: *Scope, src: usize, err_msg: *Com }, .block => { const block = scope.cast(Scope.Block).?; - if (block.func) |func| { - func.state = .sema_failure; + if (block.inlining) |*inlining| { + if (inlining.caller) |func| { + func.state = .sema_failure; + } else { + block.decl.analysis = .sema_failure; + block.decl.generation = self.generation; + } } else { - block.decl.analysis = .sema_failure; - block.decl.generation = self.generation; + if (block.func) |func| { + func.state = .sema_failure; + } else { + block.decl.analysis = .sema_failure; + block.decl.generation = self.generation; + } } self.failed_decls.putAssumeCapacityNoClobber(block.decl, err_msg); }, @@ -3414,6 +3428,7 @@ pub fn addSafetyCheck(mod: *Module, parent_block: *Scope.Block, ok: *Inst, panic .decl = parent_block.decl, .instructions = .{}, .arena = parent_block.arena, + .inlining = parent_block.inlining, .is_comptime = parent_block.is_comptime, }; defer fail_block.instructions.deinit(mod.gpa); |
