title: Why are result types of control flow instructions arbitrary? (Especially `return`)
body: <p>I am trying to understand the type system of WebAssembly and confused by control flow instructions. I don't understand <strong>why the result type of <code>br</code>, <code>result</code> or <code>unreachable</code> is an arbitrary type sequence</strong> (t_2^*):</p>
  
  <ul>
  <li><p><a href="https://webassembly.github.io/spec/core/valid/instructions.html#valid-return" rel="nofollow noreferrer">https://webassembly.github.io/spec/core/valid/instructions.html#valid-return</a></p></li>
  <li><p><a href="https://webassembly.github.io/spec/core/valid/instructions.html#valid-br" rel="nofollow noreferrer">https://webassembly.github.io/spec/core/valid/instructions.html#valid-br</a></p></li>
  <li><p><a href="https://webassembly.github.io/spec/core/valid/instructions.html#valid-unreachable" rel="nofollow noreferrer">https://webassembly.github.io/spec/core/valid/instructions.html#valid-unreachable</a></p></li>
  </ul>
  
  <p>I ran the following two snippets in the <a href="https://github.com/WebAssembly/spec/tree/master/interpreter" rel="nofollow noreferrer">reference interpreter</a>:</p>
  
  <pre><code> (module
     (func (result i32)
       (i32.const 1)
       (i32.const 2)
       (return)
       (return)
     )
   )
  </code></pre>
  
  <p>No type error is reported. However, this one:</p>
  
  <pre><code> (module
     (func (result i32)
       (i32.const 1)
       (i32.const 2)
       (return)
       (f32.const 2)
     )
   )
  </code></pre>
  
  <p>Now I get type error: "test.wast:2.2-7.3: invalid module: type mismatch: operator requires [i32] but stack has [f32]".</p>
  
  <p>But I can try and exploit the "arbitrary type sequence" and write weird programs that are still well-typed:</p>
  
  <pre><code>(module
   (func (result i32)
    (i32.const 1)
    (i32.const 2)
    (return)
    (i32.add)
    (i32.add)
    (i32.add)
    (i32.add)
    (i32.add)
    (i32.add)
    (i32.add)
   )
  )
  </code></pre>
  
  <p>So what is the point of type checking after the return statement?</p>