| ... | @@ -33,7 +33,10 @@ pub const Error = error{ | ... | @@ -33,7 +33,10 @@ pub const Error = error{ |
| 33 | | 33 | |
| 34 | // TODO: add handling of this | 34 | // TODO: add handling of this |
| 35 | TooManyValues, | 35 | TooManyValues, |
| | 36 | // TODO: add handling of this |
| 36 | HasNulls, | 37 | HasNulls, |
| | 38 | // TODO: remove this from the primary error set |
| | 39 | HitNoReturn, |
| 37 | | 40 | |
| 38 | OutOfMemory, | 41 | OutOfMemory, |
| 39 | } || Comp.File.GetTegError; | 42 | } || Comp.File.GetTegError; |
| ... | @@ -210,11 +213,14 @@ pub fn analyzeBlock(s: *Sema, in: Teg.Inst.Index) Error!Air.Inst.Ref { | ... | @@ -210,11 +213,14 @@ pub fn analyzeBlock(s: *Sema, in: Teg.Inst.Index) Error!Air.Inst.Ref { |
| 210 | const block = try s.addBlock(); | 213 | const block = try s.addBlock(); |
| 211 | try s.inst_map.add(in, block.block_index.toRef()); | 214 | try s.inst_map.add(in, block.block_index.toRef()); |
| 212 | | 215 | |
| 213 | var last: Air.Inst.Ref = undefined; | 216 | var last: Air.Inst.Ref = Value.void.toAir(); |
| 214 | const instructions = s.code.blockInstructions(in); | 217 | const instructions = s.code.blockInstructions(in); |
| 215 | assert(instructions.len != 0); | 218 | assert(instructions.len != 0); |
| 216 | for (instructions) |inst| { | 219 | for (instructions) |inst| { |
| 217 | last = try s.analyzeCode(inst); | 220 | last = s.analyzeCode(inst) catch |err| switch (err) { |
| | 221 | error.HitNoReturn => break, |
| | 222 | else => return err, |
| | 223 | }; |
| 218 | } | 224 | } |
| 219 | | 225 | |
| 220 | if (scratch_top + 1 == s.scratch.items.len) { | 226 | if (scratch_top + 1 == s.scratch.items.len) { |
| ... | @@ -585,7 +591,10 @@ fn analyzeRefToBlock(s: *Sema, in: Teg.Inst.Ref) Error!Air.Inst.Ref { | ... | @@ -585,7 +591,10 @@ fn analyzeRefToBlock(s: *Sema, in: Teg.Inst.Ref) Error!Air.Inst.Ref { |
| 585 | const scratch_top = s.scratch.items.len; | 591 | const scratch_top = s.scratch.items.len; |
| 586 | defer s.scratch.shrinkRetainingCapacity(scratch_top); | 592 | defer s.scratch.shrinkRetainingCapacity(scratch_top); |
| 587 | | 593 | |
| 588 | const visited = try s.resolveRefRuntime(in); | 594 | const visited = s.resolveRefRuntime(in) catch |err| switch (err) { |
| | 595 | error.HitNoReturn => Value.void.toAir(), |
| | 596 | else => return err, |
| | 597 | }; |
| 589 | | 598 | |
| 590 | if (scratch_top == s.scratch.items.len and visited.kind == .value) { | 599 | if (scratch_top == s.scratch.items.len and visited.kind == .value) { |
| 591 | return visited; | 600 | return visited; |
| ... | @@ -665,6 +674,9 @@ fn coerceRef(s: *Sema, src: InstOp, value: Air.Inst.Ref, to: Type) !Air.Inst.Ref | ... | @@ -665,6 +674,9 @@ fn coerceRef(s: *Sema, src: InstOp, value: Air.Inst.Ref, to: Type) !Air.Inst.Ref |
| 665 | if (from == to) { | 674 | if (from == to) { |
| 666 | return value; | 675 | return value; |
| 667 | } | 676 | } |
| | 677 | if (from == .noreturn) { |
| | 678 | return error.HitNoReturn; |
| | 679 | } |
| 668 | if (from == .@"opaque") { | 680 | if (from == .@"opaque") { |
| 669 | return value; | 681 | return value; |
| 670 | } | 682 | } |