#127sema: implement break from blocks that are not the current block

  • avatar~clovercommented · 1 year ago
    Author
    Owner
    let print = @extern("console").log;
    
    fn something(a: int) -> bool {
      if a == 0 {
        return false;
      }
    
      a > 100
    }
    
    fn main {
      print(something(0xFF), something(0));
    }
    

    This generates the following Hir:

    %0 = +0 module {
      ...
      %8 = +0 declaration something (16) [fb5a2dd6240dea2dfe9fd8bd5899c752] (
        %22 = +0 block [
          %21 = +0 func {
            params:  [ %int32_type ]
            return_type: %bool_type
            captures:  []
            body: %9 = -1 block [
              %10 = -1 param(0)
              %11 = -10 number 0
              %12 = -9 eq(%10, %11)
              %15 = -5 if(%12) {
                yes: %14 = -6 block [
                  %13 = -7 break(%9, %bool_false)
                ]
                no: %void
              }
              %16 = -5 ensure_void(%15)
              %17 = -3 number 100
              %18 = -2 gt(%10, %17)
              %19 = -1 coercion(%bool_type, %18)
              %20 = -1 break(%9, %19)
            ]
          }
          %23 = +0 break(%22, %21)
        ]
      )
      ...
    }
    

    Analyzing %13 hits a TODO because the block %9 is not the current frame's block (%13). Semantic analysis must emit an Air break instruction, mark %14 as comptime known .never, then continue analysis of %15 and analyze instructions %16 through %20. It would also coerce %bool_false to the result type of %9, which I don't remember off the top of my head how that even works.

    I think this is a regression from 0.1.6 but I am not certain.


    Milestone: 0.2.0.

  • avatar~clover changed the status to Todo · 1 year ago