;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.

;; RUN: wasm-opt -all --preserve-type-order %s -S -o - | filecheck %s

(module
  ;; CHECK:      (type $array8 (array (mut i8)))
  (type $array8 (array (mut i8)))
  ;; CHECK:      (type $array16 (array (mut i16)))
  (type $array16 (array (mut i16)))
  ;; CHECK:      (type $shared-array8 (shared (array (mut i8))))
  (type $shared-array8 (shared (array (mut i8))))
  ;; CHECK:      (type $shared-array16 (shared (array (mut i16))))
  (type $shared-array16 (shared (array (mut i16))))

  ;; CHECK:      (func $i8-bad-array (type $4) (result (ref string))
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block (result (ref array))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (string.new_lossy_utf8_array
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i8-bad-array (result (ref string))
    ;; This is not a specific array type, so it must not be popped as the first
    ;; child of the string.new.
    block (result (ref array))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_lossy_utf8_array
  )

  ;; CHECK:      (func $i8-bad-array16 (type $4) (result (ref string))
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block (result (ref $array16))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (string.new_lossy_utf8_array
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i8-bad-array16 (result (ref string))
    ;; As above, with an array with the wrong element type.
    block (result (ref $array16))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_lossy_utf8_array
  )

  ;; CHECK:      (func $i8-ok (type $4) (result (ref string))
  ;; CHECK-NEXT:  (string.new_lossy_utf8_array
  ;; CHECK-NEXT:   (block (result (ref $array8))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i8-ok (result (ref string))
    ;; Now we have the correct type, so it can be popped as the first child of
    ;; the string.new.
    block (result (ref $array8))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_lossy_utf8_array
  )

  ;; CHECK:      (func $i8-ok-none (type $4) (result (ref string))
  ;; CHECK-NEXT:  (string.new_lossy_utf8_array
  ;; CHECK-NEXT:   (block (result (ref none))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i8-ok-none (result (ref string))
    ;; Due to subsumption, bottom references must also be valid.
    block (result (ref none))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_lossy_utf8_array
  )

  ;; CHECK:      (func $i8-bad-shared (type $4) (result (ref string))
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block (result (ref $shared-array8))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (string.new_lossy_utf8_array
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i8-bad-shared (result (ref string))
    ;; Shared arrays do not work as well. TODO: find a good way to support them.
    block (result (ref $shared-array8))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_lossy_utf8_array
  )

  ;; CHECK:      (func $i8-bad-shared-none (type $4) (result (ref string))
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block (result (ref (shared none)))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (string.new_lossy_utf8_array
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i8-bad-shared-none (result (ref string))
    ;; Shared bottom references also do not work.
    block (result (ref (shared none)))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_lossy_utf8_array
  )

  ;; CHECK:      (func $i16-bad-array (type $4) (result (ref string))
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block (result (ref array))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (string.new_wtf16_array
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i16-bad-array (result (ref string))
    block (result (ref array))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_wtf16_array
  )

  ;; CHECK:      (func $i16-bad-array8 (type $4) (result (ref string))
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block (result (ref $array8))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (string.new_wtf16_array
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i16-bad-array8 (result (ref string))
    block (result (ref $array8))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_wtf16_array
  )

  ;; CHECK:      (func $i16-ok (type $4) (result (ref string))
  ;; CHECK-NEXT:  (string.new_wtf16_array
  ;; CHECK-NEXT:   (block (result (ref $array16))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i16-ok (result (ref string))
    block (result (ref $array16))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_wtf16_array
  )

  ;; CHECK:      (func $i16-ok-none (type $4) (result (ref string))
  ;; CHECK-NEXT:  (string.new_wtf16_array
  ;; CHECK-NEXT:   (block (result (ref none))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i16-ok-none (result (ref string))
    block (result (ref none))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_wtf16_array
  )

  ;; CHECK:      (func $i16-bad-shared (type $4) (result (ref string))
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block (result (ref $shared-array16))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (string.new_wtf16_array
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i16-bad-shared (result (ref string))
    block (result (ref $shared-array16))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_wtf16_array
  )

  ;; CHECK:      (func $i16-bad-shared-none (type $4) (result (ref string))
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (block (result (ref (shared none)))
  ;; CHECK-NEXT:    (unreachable)
  ;; CHECK-NEXT:   )
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (drop
  ;; CHECK-NEXT:   (i32.const 0)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT:  (string.new_wtf16_array
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:   (unreachable)
  ;; CHECK-NEXT:  )
  ;; CHECK-NEXT: )
  (func $i16-bad-shared-none (result (ref string))
    block (result (ref (shared none)))
      unreachable
    end
    i32.const 0
    unreachable
    string.new_wtf16_array
  )
)
