#113lazy discovery of missing result types

  • avatar~clovercommented · 2 years ago
    Author
    Owner

    consider this snippet

    fn hello(branch: bool) -> int {
        let y = if branch {
            1
        } else {
            2
        };
        y
    }
    

    currently with the commit im working on, since branch is not known at compile time, both of the branches of the if get their result coerced to a runtime operand. for numeric literals, this means a result type is required, meaning let y needs to be let y: int for this code to compile.

    to get us all on the same page, let's see the untyped IR for this block.

    %26 = +0 func {
      params:  [
        %bool_type
      ]
      return_type: %int32_type
      captures:  []
      body: %15 = -1 block [
        %16 = -1 param(0)
        %23 = -4 if(%16) {
          yes: %18 = -7 block [
            %17 = -8 number 1
            %19 = -7 break(%18, %17)
          ]
          no: %21 = -5 block [
            %20 = -6 number 2
            %22 = -5 break(%21, %20)
          ]
        }
        %24 = -1 coercion(%int32_type, %23)
        %25 = -1 break(%15, %24)
      ]
    }
    

    is there a way we can resolve the coersion for %18 and %21 AFTER %23 already happens? it would mean that at %24, it would see %23 is unresolved, and propagate the type backwards. one of the problems is finding old, already committed blocks, and rebuilding them.

    i'm not really sure how this will work in practice, as well as other situations where this behavior makes more sense to support. this is the same class of issue as something like

    let arr = [];
    arr.push("hello")
    

    where the the ref arr is retroactively coerced to []string


    Milestone: 0.3.0.

  • avatar~clover changed the status to Todo · 2 years ago