use std::{ fs, path::PathBuf, process::{Command, Output}, sync::atomic::{AtomicUsize, Ordering}, }; static NEXT_FIXTURE_ID: AtomicUsize = AtomicUsize::new(0); macro_rules! unsafe_required_source { ($head:literal) => { concat!( "\n(module main)\n\n(fn main () -> i32\n (", $head, " i32))\n" ) }; } macro_rules! unsupported_unsafe_source { ($head:literal) => { concat!( "\n(module main)\n\n(fn main () -> i32\n (unsafe\n (", $head, " i32)))\n" ) }; } const CASES: &[DiagnosticCase] = &[ DiagnosticCase { name: "unknown-function", source: r#" (module main) (fn main () -> i32 (missing 1)) "#, snapshot: "../tests/unknown-function.diag", }, DiagnosticCase { name: "arity-mismatch", source: r#" (module main) (fn add ((a i32) (b i32)) -> i32 (+ a b)) (fn main () -> i32 (add 1)) "#, snapshot: "../tests/arity-mismatch.diag", }, DiagnosticCase { name: "type-mismatch", source: r#" (module main) (fn id ((value i32)) -> i32 value) (fn main () -> i32 (id true)) "#, snapshot: "../tests/type-mismatch.diag", }, DiagnosticCase { name: "unclosed-list", source: r#" (module main) (fn main () -> i32 (+ 1 2) "#, snapshot: "../tests/unclosed-list.diag", }, DiagnosticCase { name: "unknown-top-level-form", source: r#" (module main) (bogus top level) "#, snapshot: "../tests/unknown-top-level-form.diag", }, DiagnosticCase { name: "enum-empty", source: r#" (module main) (enum Empty) (fn main () -> i32 0) "#, snapshot: "../tests/enum-empty.diag", }, DiagnosticCase { name: "enum-duplicate", source: r#" (module main) (enum Color Red) (enum Color Blue) (fn main () -> i32 0) "#, snapshot: "../tests/enum-duplicate.diag", }, DiagnosticCase { name: "enum-duplicate-variant", source: r#" (module main) (enum Color Red Red) (fn main () -> i32 0) "#, snapshot: "../tests/enum-duplicate-variant.diag", }, DiagnosticCase { name: "enum-unknown-constructor", source: r#" (module main) (fn main () -> i32 (Missing.Red)) "#, snapshot: "../tests/enum-unknown-constructor.diag", }, DiagnosticCase { name: "enum-unknown-variant", source: r#" (module main) (enum Color Red) (fn main () -> Color (Color.Blue)) "#, snapshot: "../tests/enum-unknown-variant.diag", }, DiagnosticCase { name: "enum-constructor-arity", source: r#" (module main) (enum Color Red) (fn main () -> Color (Color.Red 1)) "#, snapshot: "../tests/enum-constructor-arity.diag", }, DiagnosticCase { name: "enum-match-non-exhaustive", source: r#" (module main) (enum Color Red Blue) (fn main () -> i32 (match (Color.Red) ((Color.Red) 1))) "#, snapshot: "../tests/enum-match-non-exhaustive.diag", }, DiagnosticCase { name: "enum-match-duplicate-arm", source: r#" (module main) (enum Color Red Blue) (fn main () -> i32 (match (Color.Red) ((Color.Red) 1) ((Color.Red) 2) ((Color.Blue) 3))) "#, snapshot: "../tests/enum-match-duplicate-arm.diag", }, DiagnosticCase { name: "enum-match-invalid-arm", source: r#" (module main) (enum Color Red) (enum Shape Circle) (fn main () -> i32 (match (Color.Red) ((Shape.Circle) 1))) "#, snapshot: "../tests/enum-match-invalid-arm.diag", }, DiagnosticCase { name: "enum-container-values", source: r#" (module main) (enum Color Red) (fn main () -> i32 (let colors (array Color 1) (array Color (Color.Red))) (let maybe (option Color) (some Color (Color.Red))) 0) "#, snapshot: "../tests/enum-container-values.diag", }, DiagnosticCase { name: "enum-struct-fields-container", source: r#" (module main) (enum Color Red) (struct Bag (colors (array Color 1)) (maybe (option Color))) (fn main () -> i32 0) "#, snapshot: "../tests/enum-struct-fields-container.diag", }, DiagnosticCase { name: "enum-printing", source: r#" (module main) (enum Color Red) (fn main () -> i32 (print_i32 (Color.Red)) 0) "#, snapshot: "../tests/enum-printing.diag", }, DiagnosticCase { name: "enum-subject-mismatch", source: r#" (module main) (enum Color Red) (enum Shape Circle) (fn main () -> bool (= (Color.Red) (Shape.Circle))) "#, snapshot: "../tests/enum-subject-mismatch.diag", }, DiagnosticCase { name: "enum-ordering", source: r#" (module main) (enum Color Red Blue) (fn main () -> bool (< (Color.Red) (Color.Blue))) "#, snapshot: "../tests/enum-ordering.diag", }, DiagnosticCase { name: "enum-match-payload-binding", source: r#" (module main) (enum Color Red Blue) (fn main () -> i32 (match (Color.Red) ((Color.Red payload) 1) ((Color.Blue) 2))) "#, snapshot: "../tests/enum-match-payload-binding.diag", }, DiagnosticCase { name: "enum-payload-unsupported-type", source: r#" (module main) (enum Reading (Value (vec i32))) (fn main () -> i32 0) "#, snapshot: "../tests/enum-payload-unsupported-type.diag", }, DiagnosticCase { name: "enum-payload-mixed-types", source: r#" (module main) (enum Reading (Value i32) (Message string)) (fn main () -> i32 0) "#, snapshot: "../tests/enum-payload-mixed-types.diag", }, DiagnosticCase { name: "enum-payload-struct-equality", source: r#" (module main) (struct Pair (left i32) (right i32)) (enum Reading Missing (Value Pair)) (fn main () -> bool (= (Reading.Value (Pair (left 1) (right 2))) (Reading.Value (Pair (left 1) (right 2))))) "#, snapshot: "../tests/enum-payload-struct-equality.diag", }, DiagnosticCase { name: "enum-payload-recursive-struct", source: r#" (module main) (struct Node (next Wrapper)) (enum Wrapper Missing (Value Node)) (fn main () -> i32 0) "#, snapshot: "../tests/enum-payload-recursive-struct.diag", }, DiagnosticCase { name: "enum-payload-constructor-arity", source: r#" (module main) (enum Reading (Value string)) (fn main () -> Reading (Reading.Value)) "#, snapshot: "../tests/enum-payload-constructor-arity.diag", }, DiagnosticCase { name: "enum-payload-constructor-type", source: r#" (module main) (enum Reading (Value string)) (fn main () -> Reading (Reading.Value 1)) "#, snapshot: "../tests/enum-payload-constructor-type.diag", }, DiagnosticCase { name: "enum-payload-match-missing-binding", source: r#" (module main) (enum Reading Missing (Value i32)) (fn main () -> i32 (match (Reading.Value 1) ((Reading.Missing) 0) ((Reading.Value) 1))) "#, snapshot: "../tests/enum-payload-match-missing-binding.diag", }, DiagnosticCase { name: "enum-unqualified-variant-constructor", source: r#" (module main) (enum Color Red) (fn main () -> Color (Red)) "#, snapshot: "../tests/enum-unqualified-variant-constructor.diag", }, DiagnosticCase { name: "unsupported-string-escape", source: r#" (module main) (fn main () -> i32 (print_string "\0") 0) "#, snapshot: "../tests/unsupported-string-escape.diag", }, DiagnosticCase { name: "unsupported-string-literal", source: concat!( "\n(module main)\n\n(fn main () -> i32\n (print_string \"zdravo ", "\u{017E}", "\")\n 0)\n" ), snapshot: "../tests/unsupported-string-literal.diag", }, DiagnosticCase { name: "unsupported-string-concatenation", source: r#" (module main) (fn main () -> string (+ "a" "b")) "#, snapshot: "../tests/unsupported-string-concatenation.diag", }, DiagnosticCase { name: "unsupported-string-array", source: r#" (module main) (fn main () -> i32 (index (array (array string 1) (array string "a")) 0)) "#, snapshot: "../tests/unsupported-string-array.diag", }, DiagnosticCase { name: "unsupported-print-unit", source: r#" (module main) (fn main () -> i32 (print_unit 0) 0) "#, snapshot: "../tests/unsupported-print-unit.diag", }, DiagnosticCase { name: "unsupported-standard-library-call", source: r#" (module main) (fn main () -> i32 (std.io.print_unit 0) 0) "#, snapshot: "../tests/unsupported-standard-library-call.diag", }, DiagnosticCase { name: "std-num-i32-to-i64-arity", source: r#" (module main) (fn main () -> i64 (std.num.i32_to_i64)) "#, snapshot: "../tests/std-num-i32-to-i64-arity.diag", }, DiagnosticCase { name: "std-num-i32-to-f64-type", source: r#" (module main) (fn main () -> f64 (std.num.i32_to_f64 1i64)) "#, snapshot: "../tests/std-num-i32-to-f64-type.diag", }, DiagnosticCase { name: "std-num-i64-to-i32-unsupported", source: r#" (module main) (fn main () -> i32 (std.num.i64_to_i32 1i64) 0) "#, snapshot: "../tests/std-num-i64-to-i32-unsupported.diag", }, DiagnosticCase { name: "std-num-i64-to-i32-result-arity", source: r#" (module main) (fn main () -> (result i32 i32) (std.num.i64_to_i32_result)) "#, snapshot: "../tests/std-num-i64-to-i32-result-arity.diag", }, DiagnosticCase { name: "std-num-i64-to-i32-result-type", source: r#" (module main) (fn main () -> (result i32 i32) (std.num.i64_to_i32_result 1)) "#, snapshot: "../tests/std-num-i64-to-i32-result-type.diag", }, DiagnosticCase { name: "std-num-i32-to-string-arity", source: r#" (module main) (fn main () -> string (std.num.i32_to_string)) "#, snapshot: "../tests/std-num-i32-to-string-arity.diag", }, DiagnosticCase { name: "std-num-i64-to-string-type", source: r#" (module main) (fn main () -> string (std.num.i64_to_string 1)) "#, snapshot: "../tests/std-num-i64-to-string-type.diag", }, DiagnosticCase { name: "std-num-f64-to-string-arity", source: r#" (module main) (fn main () -> string (std.num.f64_to_string)) "#, snapshot: "../tests/std-num-f64-to-string-arity.diag", }, DiagnosticCase { name: "std-num-f64-to-string-type", source: r#" (module main) (fn main () -> string (std.num.f64_to_string 1)) "#, snapshot: "../tests/std-num-f64-to-string-type.diag", }, DiagnosticCase { name: "std-num-f64-to-string-context", source: r#" (module main) (fn main () -> i32 (std.num.f64_to_string 1.0) ) "#, snapshot: "../tests/std-num-f64-to-string-context.diag", }, DiagnosticCase { name: "std-num-f64-to-string-bool-context", source: r#" (module main) (fn main () -> i32 (if (std.num.f64_to_string 1.0) 1 0)) "#, snapshot: "../tests/std-num-f64-to-string-bool-context.diag", }, DiagnosticCase { name: "std-num-f64-to-string-name-shadow", source: r#" (module main) (fn std.num.f64_to_string ((value f64)) -> string "0.0") (fn main () -> i32 0) "#, snapshot: "../tests/std-num-f64-to-string-name-shadow.diag", }, DiagnosticCase { name: "std-num-f64-to-string-helper-shadow", source: r#" (module main) (fn __glagol_num_f64_to_string ((value f64)) -> string "0.0") (fn main () -> i32 0) "#, snapshot: "../tests/std-num-f64-to-string-helper-shadow.diag", }, DiagnosticCase { name: "std-num-to-string-unsupported", source: r#" (module main) (fn main () -> i32 (std.num.to_string 1) 0) "#, snapshot: "../tests/std-num-to-string-unsupported.diag", }, DiagnosticCase { name: "std-string-from-i64-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.from_i64 1i64) 0) "#, snapshot: "../tests/std-string-from-i64-unsupported.diag", }, DiagnosticCase { name: "std-num-i32-to-i64-result-unsupported", source: r#" (module main) (fn main () -> i32 (std.num.i32_to_i64_result 1) 0) "#, snapshot: "../tests/std-num-i32-to-i64-result-unsupported.diag", }, DiagnosticCase { name: "std-num-f64-to-i32-unsupported", source: r#" (module main) (fn main () -> i32 (std.num.f64_to_i32 1.0) 0) "#, snapshot: "../tests/std-num-f64-to-i32-unsupported.diag", }, DiagnosticCase { name: "std-num-f64-to-i64-unsupported", source: r#" (module main) (fn main () -> i32 (std.num.f64_to_i64 1.0) 0) "#, snapshot: "../tests/std-num-f64-to-i64-unsupported.diag", }, DiagnosticCase { name: "std-num-f64-to-i32-result-arity", source: r#" (module main) (fn main () -> (result i32 i32) (std.num.f64_to_i32_result)) "#, snapshot: "../tests/std-num-f64-to-i32-result-arity.diag", }, DiagnosticCase { name: "std-num-f64-to-i32-result-type", source: r#" (module main) (fn main () -> (result i32 i32) (std.num.f64_to_i32_result 1)) "#, snapshot: "../tests/std-num-f64-to-i32-result-type.diag", }, DiagnosticCase { name: "std-num-f64-to-i32-result-context", source: r#" (module main) (fn main () -> i32 (std.num.f64_to_i32_result 1.0)) "#, snapshot: "../tests/std-num-f64-to-i32-result-context.diag", }, DiagnosticCase { name: "std-num-f64-to-i32-result-bool-context", source: r#" (module main) (fn main () -> i32 (if (std.num.f64_to_i32_result 1.0) 1 0)) "#, snapshot: "../tests/std-num-f64-to-i32-result-bool-context.diag", }, DiagnosticCase { name: "std-num-f64-to-i32-result-name-shadow", source: r#" (module main) (fn std.num.f64_to_i32_result ((value f64)) -> (result i32 i32) (ok 0)) (fn main () -> i32 0) "#, snapshot: "../tests/std-num-f64-to-i32-result-name-shadow.diag", }, DiagnosticCase { name: "std-num-f64-to-i64-result-arity", source: r#" (module main) (fn main () -> (result i64 i32) (std.num.f64_to_i64_result)) "#, snapshot: "../tests/std-num-f64-to-i64-result-arity.diag", }, DiagnosticCase { name: "std-num-f64-to-i64-result-type", source: r#" (module main) (fn main () -> (result i64 i32) (std.num.f64_to_i64_result 1)) "#, snapshot: "../tests/std-num-f64-to-i64-result-type.diag", }, DiagnosticCase { name: "std-num-f64-to-i64-result-context", source: r#" (module main) (fn main () -> i32 (std.num.f64_to_i64_result 1.0)) "#, snapshot: "../tests/std-num-f64-to-i64-result-context.diag", }, DiagnosticCase { name: "std-num-f64-to-i64-result-bool-context", source: r#" (module main) (fn main () -> i32 (if (std.num.f64_to_i64_result 1.0) 1 0)) "#, snapshot: "../tests/std-num-f64-to-i64-result-bool-context.diag", }, DiagnosticCase { name: "std-num-f64-to-i64-result-name-shadow", source: r#" (module main) (fn std.num.f64_to_i64_result ((value f64)) -> (result i64 i32) (ok 0i64)) (fn main () -> i32 0) "#, snapshot: "../tests/std-num-f64-to-i64-result-name-shadow.diag", }, DiagnosticCase { name: "std-num-cast-unsupported", source: r#" (module main) (fn main () -> i32 (std.num.cast 1) 0) "#, snapshot: "../tests/std-num-cast-unsupported.diag", }, DiagnosticCase { name: "std-num-cast-checked-unsupported", source: r#" (module main) (fn main () -> i32 (std.num.cast_checked 1) 0) "#, snapshot: "../tests/std-num-cast-checked-unsupported.diag", }, DiagnosticCase { name: "print-bool-arity", source: r#" (module main) (fn main () -> i32 (print_bool true false) 0) "#, snapshot: "../tests/print-bool-arity.diag", }, DiagnosticCase { name: "std-print-bool-arity", source: r#" (module main) (fn main () -> i32 (std.io.print_bool true false) 0) "#, snapshot: "../tests/std-print-bool-arity.diag", }, DiagnosticCase { name: "print-bool-type", source: r#" (module main) (fn main () -> i32 (print_bool 1) 0) "#, snapshot: "../tests/print-bool-type.diag", }, DiagnosticCase { name: "string-len-arity", source: r#" (module main) (fn main () -> i32 (string_len "a" "b")) "#, snapshot: "../tests/string-len-arity.diag", }, DiagnosticCase { name: "string-len-type", source: r#" (module main) (fn main () -> i32 (string_len 1)) "#, snapshot: "../tests/string-len-type.diag", }, DiagnosticCase { name: "std-string-len-type", source: r#" (module main) (fn main () -> i32 (std.string.len 1)) "#, snapshot: "../tests/std-string-len-type.diag", }, DiagnosticCase { name: "std-string-concat-arity", source: r#" (module main) (fn main () -> string (std.string.concat "a")) "#, snapshot: "../tests/std-string-concat-arity.diag", }, DiagnosticCase { name: "std-string-concat-type", source: r#" (module main) (fn main () -> string (std.string.concat 1 "a")) "#, snapshot: "../tests/std-string-concat-type.diag", }, DiagnosticCase { name: "std-string-concat-result-context", source: r#" (module main) (fn main () -> i32 (std.string.concat "a" "b")) "#, snapshot: "../tests/std-string-concat-result-context.diag", }, DiagnosticCase { name: "std-string-concat-helper-shadow", source: r#" (module main) (fn __glagol_string_concat ((left string) (right string)) -> string "intercepted") (fn main () -> string (std.string.concat "a" "b")) "#, snapshot: "../tests/std-string-concat-helper-shadow.diag", }, DiagnosticCase { name: "std-string-concat-unsupported-string-container", source: r#" (module main) (fn main () -> string (std.string.concat (array string "a") "b")) "#, snapshot: "../tests/std-string-concat-unsupported-string-container.diag", }, DiagnosticCase { name: "std-string-parse-i32-result-arity", source: r#" (module main) (fn main () -> (result i32 i32) (std.string.parse_i32_result)) "#, snapshot: "../tests/std-string-parse-i32-result-arity.diag", }, DiagnosticCase { name: "std-string-parse-i32-result-type", source: r#" (module main) (fn main () -> (result i32 i32) (std.string.parse_i32_result 1)) "#, snapshot: "../tests/std-string-parse-i32-result-type.diag", }, DiagnosticCase { name: "std-string-parse-i32-result-context", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_result "42")) "#, snapshot: "../tests/std-string-parse-i32-result-context.diag", }, DiagnosticCase { name: "std-string-parse-i32-result-bool-context", source: r#" (module main) (fn main () -> i32 (if (std.string.parse_i32_result "42") 1 0)) "#, snapshot: "../tests/std-string-parse-i32-result-bool-context.diag", }, DiagnosticCase { name: "std-string-parse-i32-result-name-shadow", source: r#" (module main) (fn std.string.parse_i32_result ((text string)) -> (result i32 i32) (err i32 i32 1)) (fn main () -> i32 0) "#, snapshot: "../tests/std-string-parse-i32-result-name-shadow.diag", }, DiagnosticCase { name: "std-string-parse-i32-result-helper-shadow", source: r#" (module main) (fn __glagol_string_parse_i32_result ((text string)) -> (result i32 i32) (err i32 i32 1)) (fn main () -> i32 0) "#, snapshot: "../tests/std-string-parse-i32-result-helper-shadow.diag", }, DiagnosticCase { name: "std-string-parse-i64-result-arity", source: r#" (module main) (fn main () -> (result i64 i32) (std.string.parse_i64_result)) "#, snapshot: "../tests/std-string-parse-i64-result-arity.diag", }, DiagnosticCase { name: "std-string-parse-i64-result-type", source: r#" (module main) (fn main () -> (result i64 i32) (std.string.parse_i64_result 1)) "#, snapshot: "../tests/std-string-parse-i64-result-type.diag", }, DiagnosticCase { name: "std-string-parse-i64-result-context", source: r#" (module main) (fn main () -> i32 (std.string.parse_i64_result "42")) "#, snapshot: "../tests/std-string-parse-i64-result-context.diag", }, DiagnosticCase { name: "std-string-parse-i64-result-bool-context", source: r#" (module main) (fn main () -> i32 (if (std.string.parse_i64_result "42") 1 0)) "#, snapshot: "../tests/std-string-parse-i64-result-bool-context.diag", }, DiagnosticCase { name: "std-string-parse-i64-result-name-shadow", source: r#" (module main) (fn std.string.parse_i64_result ((text string)) -> (result i64 i32) (err i64 i32 1)) (fn main () -> i32 0) "#, snapshot: "../tests/std-string-parse-i64-result-name-shadow.diag", }, DiagnosticCase { name: "std-string-parse-i64-result-helper-shadow", source: r#" (module main) (fn __glagol_string_parse_i64_result ((text string)) -> (result i64 i32) (err i64 i32 1)) (fn main () -> i32 0) "#, snapshot: "../tests/std-string-parse-i64-result-helper-shadow.diag", }, DiagnosticCase { name: "std-string-parse-f64-result-arity", source: r#" (module main) (fn main () -> (result f64 i32) (std.string.parse_f64_result)) "#, snapshot: "../tests/std-string-parse-f64-result-arity.diag", }, DiagnosticCase { name: "std-string-parse-f64-result-type", source: r#" (module main) (fn main () -> (result f64 i32) (std.string.parse_f64_result 1)) "#, snapshot: "../tests/std-string-parse-f64-result-type.diag", }, DiagnosticCase { name: "std-string-parse-f64-result-context", source: r#" (module main) (fn main () -> i32 (std.string.parse_f64_result "1.0")) "#, snapshot: "../tests/std-string-parse-f64-result-context.diag", }, DiagnosticCase { name: "std-string-parse-f64-result-bool-context", source: r#" (module main) (fn main () -> i32 (if (std.string.parse_f64_result "1.0") 1 0)) "#, snapshot: "../tests/std-string-parse-f64-result-bool-context.diag", }, DiagnosticCase { name: "std-string-parse-f64-result-name-shadow", source: r#" (module main) (fn std.string.parse_f64_result ((text string)) -> (result f64 i32) (std.string.parse_f64_result text)) (fn main () -> i32 0) "#, snapshot: "../tests/std-string-parse-f64-result-name-shadow.diag", }, DiagnosticCase { name: "std-string-parse-f64-result-helper-shadow", source: r#" (module main) (fn __glagol_string_parse_f64_result ((text string)) -> (result f64 i32) (std.string.parse_f64_result text)) (fn main () -> i32 0) "#, snapshot: "../tests/std-string-parse-f64-result-helper-shadow.diag", }, DiagnosticCase { name: "std-string-parse-bool-result-arity", source: r#" (module main) (fn main () -> (result bool i32) (std.string.parse_bool_result)) "#, snapshot: "../tests/std-string-parse-bool-result-arity.diag", }, DiagnosticCase { name: "std-string-parse-bool-result-type", source: r#" (module main) (fn main () -> (result bool i32) (std.string.parse_bool_result 1)) "#, snapshot: "../tests/std-string-parse-bool-result-type.diag", }, DiagnosticCase { name: "std-string-parse-bool-result-context", source: r#" (module main) (fn main () -> i32 (std.string.parse_bool_result "true")) "#, snapshot: "../tests/std-string-parse-bool-result-context.diag", }, DiagnosticCase { name: "std-string-parse-bool-result-bool-context", source: r#" (module main) (fn main () -> i32 (if (std.string.parse_bool_result "true") 1 0)) "#, snapshot: "../tests/std-string-parse-bool-result-bool-context.diag", }, DiagnosticCase { name: "std-string-parse-bool-result-name-shadow", source: r#" (module main) (fn std.string.parse_bool_result ((text string)) -> (result bool i32) (std.string.parse_bool_result text)) (fn main () -> i32 0) "#, snapshot: "../tests/std-string-parse-bool-result-name-shadow.diag", }, DiagnosticCase { name: "std-string-parse-bool-result-helper-shadow", source: r#" (module main) (fn __glagol_string_parse_bool_result ((text string)) -> (result bool i32) (std.string.parse_bool_result text)) (fn main () -> i32 0) "#, snapshot: "../tests/std-string-parse-bool-result-helper-shadow.diag", }, DiagnosticCase { name: "std-string-parse-i32-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32 "42") 0) "#, snapshot: "../tests/std-string-parse-i32-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-f64-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_f64 "1.0") 0) "#, snapshot: "../tests/std-string-parse-f64-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-bool-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_bool "true") 0) "#, snapshot: "../tests/std-string-parse-bool-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-string-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_string_result "text") 0) "#, snapshot: "../tests/std-string-parse-string-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-bytes-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_bytes_result "42") 0) "#, snapshot: "../tests/std-string-parse-bytes-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-trim-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_trim_result " 42 ") 0) "#, snapshot: "../tests/std-string-parse-i32-trim-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-whitespace-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_whitespace_result " 42 ") 0) "#, snapshot: "../tests/std-string-parse-i32-whitespace-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-locale-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_locale_result "42" "hr-HR") 0) "#, snapshot: "../tests/std-string-parse-i32-locale-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-base-prefix-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_base_prefix_result "0x2a") 0) "#, snapshot: "../tests/std-string-parse-i32-base-prefix-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-binary-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_binary_result "101010") 0) "#, snapshot: "../tests/std-string-parse-i32-binary-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-octal-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_octal_result "52") 0) "#, snapshot: "../tests/std-string-parse-i32-octal-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-hex-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_hex_result "2a") 0) "#, snapshot: "../tests/std-string-parse-i32-hex-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-radix-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_radix_result "2a" 16) 0) "#, snapshot: "../tests/std-string-parse-i32-radix-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-underscore-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_underscore_result "1_000") 0) "#, snapshot: "../tests/std-string-parse-i32-underscore-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-plus-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_plus_result "+42") 0) "#, snapshot: "../tests/std-string-parse-i32-plus-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-generic-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_result "42") 0) "#, snapshot: "../tests/std-string-parse-generic-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-message-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_message_result "nope") 0) "#, snapshot: "../tests/std-string-parse-i32-message-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-code-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_code_result "nope") 0) "#, snapshot: "../tests/std-string-parse-i32-code-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-error-adt-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_error_result "nope") 0) "#, snapshot: "../tests/std-string-parse-i32-error-adt-unsupported.diag", }, DiagnosticCase { name: "std-string-parse-i32-unicode-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.parse_i32_unicode_result "42") 0) "#, snapshot: "../tests/std-string-parse-i32-unicode-unsupported.diag", }, DiagnosticCase { name: "std-string-index-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.index "42" 0)) "#, snapshot: "../tests/std-string-index-unsupported.diag", }, DiagnosticCase { name: "std-string-slice-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.slice "42" 0 1) 0) "#, snapshot: "../tests/std-string-slice-unsupported.diag", }, DiagnosticCase { name: "std-string-tokenize-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.tokenize "1 2") 0) "#, snapshot: "../tests/std-string-tokenize-unsupported.diag", }, DiagnosticCase { name: "std-string-scan-unsupported", source: r#" (module main) (fn main () -> i32 (std.string.scan "42") 0) "#, snapshot: "../tests/std-string-scan-unsupported.diag", }, DiagnosticCase { name: "std-io-eprint-arity", source: r#" (module main) (fn main () -> i32 (std.io.eprint "a" "b") 0) "#, snapshot: "../tests/std-io-eprint-arity.diag", }, DiagnosticCase { name: "std-process-arg-type", source: r#" (module main) (fn main () -> string (std.process.arg true)) "#, snapshot: "../tests/std-process-arg-type.diag", }, DiagnosticCase { name: "std-env-get-type", source: r#" (module main) (fn main () -> string (std.env.get 1)) "#, snapshot: "../tests/std-env-get-type.diag", }, DiagnosticCase { name: "std-fs-write-text-arity", source: r#" (module main) (fn main () -> i32 (std.fs.write_text "path")) "#, snapshot: "../tests/std-fs-write-text-arity.diag", }, DiagnosticCase { name: "std-io-eprint-result-context", source: r#" (module main) (fn main () -> i32 (std.io.eprint "not an i32")) "#, snapshot: "../tests/std-io-eprint-result-context.diag", }, DiagnosticCase { name: "std-fs-read-text-helper-shadow", source: r#" (module main) (fn __glagol_fs_read_text ((path string)) -> string "intercepted") (fn main () -> string (std.fs.read_text "path")) "#, snapshot: "../tests/std-fs-read-text-helper-shadow.diag", }, DiagnosticCase { name: "std-fs-read-binary-unsupported-alias", source: r#" (module main) (fn main () -> string (std.fs.read_binary "path")) "#, snapshot: "../tests/std-fs-read-binary-unsupported-alias.diag", }, DiagnosticCase { name: "std-net-connect-unsupported", source: r#" (module main) (fn main () -> i32 (std.net.connect "host") 0) "#, snapshot: "../tests/std-net-connect-unsupported.diag", }, DiagnosticCase { name: "std-async-spawn-unsupported", source: r#" (module main) (fn main () -> i32 (std.async.spawn 0) 0) "#, snapshot: "../tests/std-async-spawn-unsupported.diag", }, DiagnosticCase { name: "std-fs-list-dir-unsupported", source: r#" (module main) (fn main () -> i32 (std.fs.list_dir ".") 0) "#, snapshot: "../tests/std-fs-list-dir-unsupported.diag", }, DiagnosticCase { name: "std-terminal-clear-unsupported", source: r#" (module main) (fn main () -> i32 (std.terminal.clear) 0) "#, snapshot: "../tests/std-terminal-clear-unsupported.diag", }, DiagnosticCase { name: "std-platform-os-unsupported", source: r#" (module main) (fn main () -> i32 (std.platform.os) 0) "#, snapshot: "../tests/std-platform-os-unsupported.diag", }, DiagnosticCase { name: "std-io-read-stdin-unsupported", source: r#" (module main) (fn main () -> i32 (std.io.read_stdin) 0) "#, snapshot: "../tests/std-io-read-stdin-unsupported.diag", }, DiagnosticCase { name: "std-io-read-line-unsupported", source: r#" (module main) (fn main () -> i32 (std.io.read_line) 0) "#, snapshot: "../tests/std-io-read-line-unsupported.diag", }, DiagnosticCase { name: "std-io-stdin-lines-unsupported", source: r#" (module main) (fn main () -> i32 (std.io.stdin_lines) 0) "#, snapshot: "../tests/std-io-stdin-lines-unsupported.diag", }, DiagnosticCase { name: "std-io-prompt-unsupported", source: r#" (module main) (fn main () -> string (std.io.prompt "name")) "#, snapshot: "../tests/std-io-prompt-unsupported.diag", }, DiagnosticCase { name: "std-terminal-raw-mode-unsupported", source: r#" (module main) (fn main () -> i32 (std.terminal.raw_mode true) 0) "#, snapshot: "../tests/std-terminal-raw-mode-unsupported.diag", }, DiagnosticCase { name: "std-terminal-echo-unsupported", source: r#" (module main) (fn main () -> i32 (std.terminal.echo false) 0) "#, snapshot: "../tests/std-terminal-echo-unsupported.diag", }, DiagnosticCase { name: "std-terminal-is-tty-unsupported", source: r#" (module main) (fn main () -> bool (std.terminal.is_tty)) "#, snapshot: "../tests/std-terminal-is-tty-unsupported.diag", }, DiagnosticCase { name: "std-io-read-stdin-binary-unsupported", source: r#" (module main) (fn main () -> i32 (std.io.read_stdin_binary) 0) "#, snapshot: "../tests/std-io-read-stdin-binary-unsupported.diag", }, DiagnosticCase { name: "std-io-read-stdin-bytes-unsupported", source: r#" (module main) (fn main () -> i32 (std.io.read_stdin_bytes) 0) "#, snapshot: "../tests/std-io-read-stdin-bytes-unsupported.diag", }, DiagnosticCase { name: "std-io-stdin-stream-unsupported", source: r#" (module main) (fn main () -> i32 (std.io.stdin_stream) 0) "#, snapshot: "../tests/std-io-stdin-stream-unsupported.diag", }, DiagnosticCase { name: "std-io-read-stdin-async-unsupported", source: r#" (module main) (fn main () -> i32 (std.io.read_stdin_async) 0) "#, snapshot: "../tests/std-io-read-stdin-async-unsupported.diag", }, DiagnosticCase { name: "std-io-stdin-encoding-unsupported", source: r#" (module main) (fn main () -> i32 (std.io.stdin_encoding) 0) "#, snapshot: "../tests/std-io-stdin-encoding-unsupported.diag", }, DiagnosticCase { name: "std-random-i32-arity", source: r#" (module main) (fn main () -> i32 (std.random.i32 1)) "#, snapshot: "../tests/std-random-i32-arity.diag", }, DiagnosticCase { name: "std-random-i32-bool-context", source: r#" (module main) (fn main () -> i32 (if (std.random.i32) 1 0)) "#, snapshot: "../tests/std-random-i32-bool-context.diag", }, DiagnosticCase { name: "std-random-i32-name-shadow", source: r#" (module main) (fn std.random.i32 () -> i32 0) (fn main () -> i32 (std.random.i32)) "#, snapshot: "../tests/std-random-i32-name-shadow.diag", }, DiagnosticCase { name: "std-random-i32-helper-shadow", source: r#" (module main) (fn __glagol_random_i32 () -> i32 0) (fn main () -> i32 (std.random.i32)) "#, snapshot: "../tests/std-random-i32-helper-shadow.diag", }, DiagnosticCase { name: "std-random-seed-unsupported", source: r#" (module main) (fn main () -> i32 (std.random.seed 1) 0) "#, snapshot: "../tests/std-random-seed-unsupported.diag", }, DiagnosticCase { name: "std-random-range-unsupported", source: r#" (module main) (fn main () -> i32 (std.random.range 0 10)) "#, snapshot: "../tests/std-random-range-unsupported.diag", }, DiagnosticCase { name: "std-random-bytes-unsupported", source: r#" (module main) (fn main () -> i32 (std.random.bytes 16) 0) "#, snapshot: "../tests/std-random-bytes-unsupported.diag", }, DiagnosticCase { name: "std-random-float-unsupported", source: r#" (module main) (fn main () -> i32 (std.random.float) 0) "#, snapshot: "../tests/std-random-float-unsupported.diag", }, DiagnosticCase { name: "std-random-shuffle-unsupported", source: r#" (module main) (fn main () -> i32 (std.random.shuffle (std.vec.i32.empty)) 0) "#, snapshot: "../tests/std-random-shuffle-unsupported.diag", }, DiagnosticCase { name: "std-random-string-unsupported", source: r#" (module main) (fn main () -> string (std.random.string 8)) "#, snapshot: "../tests/std-random-string-unsupported.diag", }, DiagnosticCase { name: "std-random-uuid-unsupported", source: r#" (module main) (fn main () -> string (std.random.uuid)) "#, snapshot: "../tests/std-random-uuid-unsupported.diag", }, DiagnosticCase { name: "std-random-crypto-i32-unsupported", source: r#" (module main) (fn main () -> i32 (std.random.crypto_i32)) "#, snapshot: "../tests/std-random-crypto-i32-unsupported.diag", }, DiagnosticCase { name: "std-time-now-unsupported", source: r#" (module main) (fn main () -> i32 (std.time.now) 0) "#, snapshot: "../tests/std-time-now-unsupported.diag", }, DiagnosticCase { name: "std-time-monotonic-arity", source: r#" (module main) (fn main () -> i32 (std.time.monotonic_ms 1)) "#, snapshot: "../tests/std-time-monotonic-arity.diag", }, DiagnosticCase { name: "std-time-monotonic-result-context", source: r#" (module main) (fn main () -> i32 (let elapsed string (std.time.monotonic_ms)) 0) "#, snapshot: "../tests/std-time-monotonic-result-context.diag", }, DiagnosticCase { name: "std-time-sleep-arity", source: r#" (module main) (fn main () -> i32 (std.time.sleep_ms) 0) "#, snapshot: "../tests/std-time-sleep-arity.diag", }, DiagnosticCase { name: "std-time-sleep-type", source: r#" (module main) (fn main () -> i32 (std.time.sleep_ms true) 0) "#, snapshot: "../tests/std-time-sleep-type.diag", }, DiagnosticCase { name: "std-time-monotonic-helper-shadow", source: r#" (module main) (fn __glagol_time_monotonic_ms () -> i32 0) (fn main () -> i32 (std.time.monotonic_ms)) "#, snapshot: "../tests/std-time-monotonic-helper-shadow.diag", }, DiagnosticCase { name: "std-time-monotonic-name-shadow", source: r#" (module main) (fn std.time.monotonic_ms () -> i32 0) (fn main () -> i32 (std.time.monotonic_ms)) "#, snapshot: "../tests/std-time-monotonic-name-shadow.diag", }, DiagnosticCase { name: "std-time-sleep-helper-shadow", source: r#" (module main) (fn __glagol_time_sleep_ms ((ms i32)) -> i32 ms) (fn main () -> i32 (std.time.sleep_ms 0) 0) "#, snapshot: "../tests/std-time-sleep-helper-shadow.diag", }, DiagnosticCase { name: "std-time-sleep-name-shadow", source: r#" (module main) (fn std.time.sleep_ms ((ms i32)) -> i32 ms) (fn main () -> i32 (std.time.sleep_ms 0) 0) "#, snapshot: "../tests/std-time-sleep-name-shadow.diag", }, DiagnosticCase { name: "std-process-arg-result-arity", source: r#" (module main) (fn main () -> i32 (std.process.arg_result) 0) "#, snapshot: "../tests/std-process-arg-result-arity.diag", }, DiagnosticCase { name: "std-env-get-result-type", source: r#" (module main) (fn main () -> i32 (std.env.get_result 1) 0) "#, snapshot: "../tests/std-env-get-result-type.diag", }, DiagnosticCase { name: "std-fs-write-text-result-arity", source: r#" (module main) (fn main () -> i32 (std.fs.write_text_result "path") 0) "#, snapshot: "../tests/std-fs-write-text-result-arity.diag", }, DiagnosticCase { name: "std-fs-write-text-result-type", source: r#" (module main) (fn main () -> i32 (std.fs.write_text_result "path" 1) 0) "#, snapshot: "../tests/std-fs-write-text-result-type.diag", }, DiagnosticCase { name: "std-process-arg-result-name-shadow", source: r#" (module main) (fn std.process.arg_result ((index i32)) -> (result string i32) (err string i32 1)) (fn main () -> i32 0) "#, snapshot: "../tests/std-process-arg-result-name-shadow.diag", }, DiagnosticCase { name: "std-process-arg-result-helper-shadow", source: r#" (module main) (fn __glagol_process_arg_result ((index i32)) -> (result string i32) (err string i32 1)) (fn main () -> i32 0) "#, snapshot: "../tests/std-process-arg-result-helper-shadow.diag", }, DiagnosticCase { name: "std-io-read-stdin-result-arity", source: r#" (module main) (fn main () -> i32 (std.io.read_stdin_result 1)) "#, snapshot: "../tests/std-io-read-stdin-result-arity.diag", }, DiagnosticCase { name: "std-io-read-stdin-result-bool-context", source: r#" (module main) (fn main () -> i32 (if (std.io.read_stdin_result) 1 0)) "#, snapshot: "../tests/std-io-read-stdin-result-bool-context.diag", }, DiagnosticCase { name: "std-io-read-stdin-result-type", source: r#" (module main) (fn main () -> i32 (let value i32 (std.io.read_stdin_result)) value) "#, snapshot: "../tests/std-io-read-stdin-result-type.diag", }, DiagnosticCase { name: "std-io-read-stdin-result-name-shadow", source: r#" (module main) (fn std.io.read_stdin_result () -> (result string i32) (err string i32 1)) (fn main () -> i32 0) "#, snapshot: "../tests/std-io-read-stdin-result-name-shadow.diag", }, DiagnosticCase { name: "std-io-read-stdin-result-helper-shadow", source: r#" (module main) (fn __glagol_io_read_stdin_result () -> (result string i32) (err string i32 1)) (fn main () -> i32 0) "#, snapshot: "../tests/std-io-read-stdin-result-helper-shadow.diag", }, DiagnosticCase { name: "std-result-map-unsupported", source: r#" (module main) (fn main () -> i32 (std.result.map (ok string i32 "a")) 0) "#, snapshot: "../tests/std-result-map-unsupported.diag", }, DiagnosticCase { name: "std-package-load-unsupported", source: r#" (module main) (fn main () -> i32 (std.package.load "dep") 0) "#, snapshot: "../tests/std-package-load-unsupported.diag", }, DiagnosticCase { name: "std-abi-layout-unsupported", source: r#" (module main) (fn main () -> i32 (std.abi.layout) 0) "#, snapshot: "../tests/std-abi-layout-unsupported.diag", }, DiagnosticCase { name: "std-vec-i32-arity", source: r#" (module main) (fn main () -> (vec i32) (std.vec.i32.append (std.vec.i32.empty))) "#, snapshot: "../tests/std-vec-i32-arity.diag", }, DiagnosticCase { name: "std-vec-i32-empty-arity", source: r#" (module main) (fn main () -> (vec i32) (std.vec.i32.empty 1)) "#, snapshot: "../tests/std-vec-i32-empty-arity.diag", }, DiagnosticCase { name: "std-vec-i32-len-arity", source: r#" (module main) (fn main () -> i32 (std.vec.i32.len)) "#, snapshot: "../tests/std-vec-i32-len-arity.diag", }, DiagnosticCase { name: "std-vec-i32-index-arity", source: r#" (module main) (fn main () -> i32 (std.vec.i32.index (std.vec.i32.empty))) "#, snapshot: "../tests/std-vec-i32-index-arity.diag", }, DiagnosticCase { name: "std-vec-i32-type", source: r#" (module main) (fn main () -> (vec i32) (std.vec.i32.append (std.vec.i32.empty) true)) "#, snapshot: "../tests/std-vec-i32-type.diag", }, DiagnosticCase { name: "std-vec-i32-append-vector-type", source: r#" (module main) (fn main () -> (vec i32) (std.vec.i32.append 1 2)) "#, snapshot: "../tests/std-vec-i32-append-vector-type.diag", }, DiagnosticCase { name: "std-vec-i32-len-type", source: r#" (module main) (fn main () -> i32 (std.vec.i32.len 1)) "#, snapshot: "../tests/std-vec-i32-len-type.diag", }, DiagnosticCase { name: "std-vec-i32-index-vector-type", source: r#" (module main) (fn main () -> i32 (std.vec.i32.index 1 0)) "#, snapshot: "../tests/std-vec-i32-index-vector-type.diag", }, DiagnosticCase { name: "std-vec-i32-index-index-type", source: r#" (module main) (fn main () -> i32 (std.vec.i32.index (std.vec.i32.empty) true)) "#, snapshot: "../tests/std-vec-i32-index-index-type.diag", }, DiagnosticCase { name: "std-vec-i32-result-context", source: r#" (module main) (fn main () -> i32 (std.vec.i32.empty)) "#, snapshot: "../tests/std-vec-i32-result-context.diag", }, DiagnosticCase { name: "std-vec-i32-one-sided-equality", source: r#" (module main) (fn main () -> bool (= (std.vec.i32.empty) 1)) "#, snapshot: "../tests/std-vec-i32-one-sided-equality.diag", }, DiagnosticCase { name: "std-vec-i32-helper-shadow", source: r#" (module main) (fn __glagol_vec_i32_eq ((left (vec i32)) (right (vec i32))) -> bool (= left right)) (fn main () -> (vec i32) (std.vec.i32.empty)) "#, snapshot: "../tests/std-vec-i32-helper-shadow.diag", }, DiagnosticCase { name: "std-vec-i32-push-alias", source: r#" (module main) (fn main () -> (vec i32) (std.vec.i32.push (std.vec.i32.empty) 1)) "#, snapshot: "../tests/std-vec-i32-push-alias.diag", }, DiagnosticCase { name: "std-vec-i64-arity", source: r#" (module main) (fn main () -> (vec i64) (std.vec.i64.append (std.vec.i64.empty))) "#, snapshot: "../tests/std-vec-i64-arity.diag", }, DiagnosticCase { name: "std-vec-i64-empty-arity", source: r#" (module main) (fn main () -> (vec i64) (std.vec.i64.empty 1)) "#, snapshot: "../tests/std-vec-i64-empty-arity.diag", }, DiagnosticCase { name: "std-vec-i64-len-arity", source: r#" (module main) (fn main () -> i32 (std.vec.i64.len)) "#, snapshot: "../tests/std-vec-i64-len-arity.diag", }, DiagnosticCase { name: "std-vec-i64-index-arity", source: r#" (module main) (fn main () -> i64 (std.vec.i64.index (std.vec.i64.empty))) "#, snapshot: "../tests/std-vec-i64-index-arity.diag", }, DiagnosticCase { name: "std-vec-i64-type", source: r#" (module main) (fn main () -> (vec i64) (std.vec.i64.append (std.vec.i64.empty) true)) "#, snapshot: "../tests/std-vec-i64-type.diag", }, DiagnosticCase { name: "std-vec-i64-append-vector-type", source: r#" (module main) (fn main () -> (vec i64) (std.vec.i64.append 1 2i64)) "#, snapshot: "../tests/std-vec-i64-append-vector-type.diag", }, DiagnosticCase { name: "std-vec-i64-len-type", source: r#" (module main) (fn main () -> i32 (std.vec.i64.len 1)) "#, snapshot: "../tests/std-vec-i64-len-type.diag", }, DiagnosticCase { name: "std-vec-i64-index-vector-type", source: r#" (module main) (fn main () -> i64 (std.vec.i64.index 1 0)) "#, snapshot: "../tests/std-vec-i64-index-vector-type.diag", }, DiagnosticCase { name: "std-vec-i64-index-index-type", source: r#" (module main) (fn main () -> i64 (std.vec.i64.index (std.vec.i64.empty) true)) "#, snapshot: "../tests/std-vec-i64-index-index-type.diag", }, DiagnosticCase { name: "std-vec-i64-result-context", source: r#" (module main) (fn main () -> i32 (std.vec.i64.empty)) "#, snapshot: "../tests/std-vec-i64-result-context.diag", }, DiagnosticCase { name: "std-vec-i64-one-sided-equality", source: r#" (module main) (fn main () -> bool (= (std.vec.i64.empty) 1)) "#, snapshot: "../tests/std-vec-i64-one-sided-equality.diag", }, DiagnosticCase { name: "std-vec-i64-helper-shadow", source: r#" (module main) (fn __glagol_vec_i64_eq ((left (vec i64)) (right (vec i64))) -> bool (= left right)) (fn main () -> (vec i64) (std.vec.i64.empty)) "#, snapshot: "../tests/std-vec-i64-helper-shadow.diag", }, DiagnosticCase { name: "std-vec-i64-push-alias", source: r#" (module main) (fn main () -> (vec i64) (std.vec.i64.push (std.vec.i64.empty) 1i64)) "#, snapshot: "../tests/std-vec-i64-push-alias.diag", }, DiagnosticCase { name: "std-vec-string-arity", source: r#" (module main) (fn main () -> (vec string) (std.vec.string.append (std.vec.string.empty))) "#, snapshot: "../tests/std-vec-string-arity.diag", }, DiagnosticCase { name: "std-vec-string-empty-arity", source: r#" (module main) (fn main () -> (vec string) (std.vec.string.empty "extra")) "#, snapshot: "../tests/std-vec-string-empty-arity.diag", }, DiagnosticCase { name: "std-vec-string-len-arity", source: r#" (module main) (fn main () -> i32 (std.vec.string.len)) "#, snapshot: "../tests/std-vec-string-len-arity.diag", }, DiagnosticCase { name: "std-vec-string-index-arity", source: r#" (module main) (fn main () -> string (std.vec.string.index (std.vec.string.empty))) "#, snapshot: "../tests/std-vec-string-index-arity.diag", }, DiagnosticCase { name: "std-vec-string-type", source: r#" (module main) (fn main () -> (vec string) (std.vec.string.append (std.vec.string.empty) 1)) "#, snapshot: "../tests/std-vec-string-type.diag", }, DiagnosticCase { name: "std-vec-string-append-vector-type", source: r#" (module main) (fn main () -> (vec string) (std.vec.string.append 1 "x")) "#, snapshot: "../tests/std-vec-string-append-vector-type.diag", }, DiagnosticCase { name: "std-vec-string-len-type", source: r#" (module main) (fn main () -> i32 (std.vec.string.len 1)) "#, snapshot: "../tests/std-vec-string-len-type.diag", }, DiagnosticCase { name: "std-vec-string-index-vector-type", source: r#" (module main) (fn main () -> string (std.vec.string.index 1 0)) "#, snapshot: "../tests/std-vec-string-index-vector-type.diag", }, DiagnosticCase { name: "std-vec-string-index-index-type", source: r#" (module main) (fn main () -> string (std.vec.string.index (std.vec.string.empty) true)) "#, snapshot: "../tests/std-vec-string-index-index-type.diag", }, DiagnosticCase { name: "std-vec-string-result-context", source: r#" (module main) (fn main () -> i32 (std.vec.string.empty)) "#, snapshot: "../tests/std-vec-string-result-context.diag", }, DiagnosticCase { name: "std-vec-string-one-sided-equality", source: r#" (module main) (fn main () -> bool (= (std.vec.string.empty) 1)) "#, snapshot: "../tests/std-vec-string-one-sided-equality.diag", }, DiagnosticCase { name: "std-vec-string-helper-shadow", source: r#" (module main) (fn __glagol_vec_string_eq ((left (vec string)) (right (vec string))) -> bool (= left right)) (fn main () -> (vec string) (std.vec.string.empty)) "#, snapshot: "../tests/std-vec-string-helper-shadow.diag", }, DiagnosticCase { name: "std-vec-string-push-alias", source: r#" (module main) (fn main () -> (vec string) (std.vec.string.push (std.vec.string.empty) "x")) "#, snapshot: "../tests/std-vec-string-push-alias.diag", }, DiagnosticCase { name: "std-print-bool-result", source: r#" (module main) (fn main () -> i32 (std.io.print_bool true)) "#, snapshot: "../tests/std-print-bool-result.diag", }, DiagnosticCase { name: "std-parameter-shadows-runtime", source: r#" (module main) (fn leak ((std.io.print_i32 i32)) -> i32 std.io.print_i32) "#, snapshot: "../tests/std-parameter-shadows-runtime.diag", }, DiagnosticCase { name: "unsafe-parameter-shadows-callable", source: r#" (module main) (fn leak ((alloc i32)) -> i32 alloc) "#, snapshot: "../tests/unsafe-parameter-shadows-callable.diag", }, DiagnosticCase { name: "integer-out-of-range", source: r#" (module main) (fn main () -> i32 2147483648) "#, snapshot: "../tests/integer-out-of-range.diag", }, DiagnosticCase { name: "i64-literal-out-of-range", source: r#" (module main) (fn main () -> i32 9223372036854775808i64) "#, snapshot: "../tests/i64-literal-out-of-range.diag", }, DiagnosticCase { name: "invalid-i64-literal", source: r#" (module main) (fn main () -> i32 1.0i64) "#, snapshot: "../tests/invalid-i64-literal.diag", }, DiagnosticCase { name: "invalid-leading-plus-i64-literal", source: r#" (module main) (fn main () -> i32 +1i64) "#, snapshot: "../tests/invalid-leading-plus-i64-literal.diag", }, DiagnosticCase { name: "invalid-sign-only-i64-literal", source: r#" (module main) (fn main () -> i32 -i64) "#, snapshot: "../tests/invalid-sign-only-i64-literal.diag", }, DiagnosticCase { name: "unsupported-float-literal", source: r#" (module main) (fn main () -> i32 (let value f64 NaN) 0) "#, snapshot: "../tests/unsupported-float-literal.diag", }, DiagnosticCase { name: "test-invalid-name", source: r#" (module main) (test not-a-string true) "#, snapshot: "../tests/test-invalid-name.diag", }, DiagnosticCase { name: "test-invalid-escaped-name", source: r#" (module main) (test "bad\nname" true) "#, snapshot: "../tests/test-invalid-escaped-name.diag", }, DiagnosticCase { name: "test-duplicate-name", source: r#" (module main) (test "same" true) (test "same" true) "#, snapshot: "../tests/test-duplicate-name.diag", }, DiagnosticCase { name: "test-non-bool", source: r#" (module main) (test "not bool" 1) "#, snapshot: "../tests/test-non-bool.diag", }, DiagnosticCase { name: "test-invalid-form", source: r#" (module main) (test "too many" true false) "#, snapshot: "../tests/test-invalid-form.diag", }, DiagnosticCase { name: "unsupported-signature-type", source: r#" (module main) (fn id ((value (ptr i32))) -> i32 0) "#, snapshot: "../tests/unsupported-signature-type.diag", }, DiagnosticCase { name: "unknown-struct-parameter", source: r#" (module main) (fn take ((value Missing)) -> i32 0) "#, snapshot: "../tests/unknown-struct-parameter.diag", }, DiagnosticCase { name: "unknown-struct-return", source: r#" (module main) (fn make () -> Missing 0) "#, snapshot: "../tests/unknown-struct-return.diag", }, DiagnosticCase { name: "unsupported-unit-return-signature", source: r#" (module main) (fn main () -> unit (print_i32 1)) "#, snapshot: "../tests/unsupported-unit-return-signature.diag", }, DiagnosticCase { name: "unsupported-unit-parameter-signature", source: r#" (module main) (fn ignore ((value unit)) -> i32 0) "#, snapshot: "../tests/unsupported-unit-parameter-signature.diag", }, DiagnosticCase { name: "empty-array", source: r#" (module main) (fn main () -> i32 (index (array i32) 0)) "#, snapshot: "../tests/empty-array.diag", }, DiagnosticCase { name: "zero-length-array-type", source: r#" (module main) (fn main () -> i32 (let values (array i32 0) (array i32 1)) 0) "#, snapshot: "../tests/zero-length-array-type.diag", }, DiagnosticCase { name: "array-index-out-of-bounds", source: r#" (module main) (fn main () -> i32 (index (array i32 1 2) 2)) "#, snapshot: "../tests/array-index-out-of-bounds.diag", }, DiagnosticCase { name: "index-on-non-array", source: r#" (module main) (fn main () -> i32 (index 1 0)) "#, snapshot: "../tests/index-on-non-array.diag", }, DiagnosticCase { name: "array-index-not-i32", source: r#" (module main) (fn main () -> i32 (index (array i32 1) true)) "#, snapshot: "../tests/array-index-not-i32.diag", }, DiagnosticCase { name: "unsupported-array-element-type", source: r#" (module main) (fn main () -> i32 (index (array (array i32 1) (array i32 1)) 0)) "#, snapshot: "../tests/unsupported-array-element-type.diag", }, DiagnosticCase { name: "unsupported-array-signature-element-type", source: r#" (module main) (fn first ((values (array (array string 1) 1))) -> i32 0) "#, snapshot: "../tests/unsupported-array-signature-element-type.diag", }, DiagnosticCase { name: "unsupported-array-equality", source: r#" (module main) (fn main () -> i32 (if (= (array i32 1) (array i32 1)) 1 0)) "#, snapshot: "../tests/unsupported-array-equality.diag", }, DiagnosticCase { name: "unsupported-array-local-mutation", source: r#" (module main) (fn main () -> i32 (var values (array i32 1) (array i32 1)) 0) "#, snapshot: "../tests/unsupported-array-local-mutation.diag", }, DiagnosticCase { name: "unsupported-array-print", source: r#" (module main) (fn main () -> i32 (print_i32 (array i32 1)) 0) "#, snapshot: "../tests/unsupported-array-print.diag", }, DiagnosticCase { name: "unsupported-vec-element-type", source: r#" (module main) (fn main ((values (vec f32))) -> i32 0) "#, snapshot: "../tests/unsupported-vec-element-type.diag", }, DiagnosticCase { name: "unsupported-generic-vec-type", source: r#" (module main) (fn main () -> (vec) (std.vec.i32.empty)) "#, snapshot: "../tests/unsupported-generic-vec-type.diag", }, DiagnosticCase { name: "unsupported-vec-nesting", source: r#" (module main) (fn main ((values (array (vec i32) 1))) -> i32 0) "#, snapshot: "../tests/unsupported-vec-nesting.diag", }, DiagnosticCase { name: "unsupported-vec-option", source: r#" (module main) (fn main () -> i32 (is_some (some (vec i32) (std.vec.i32.empty)))) "#, snapshot: "../tests/unsupported-vec-option.diag", }, DiagnosticCase { name: "unsupported-vec-result", source: r#" (module main) (fn main () -> i32 (is_ok (ok (vec i32) i32 (std.vec.i32.empty)))) "#, snapshot: "../tests/unsupported-vec-result.diag", }, DiagnosticCase { name: "unsupported-vec-literal", source: r#" (module main) (fn main () -> (vec i32) (vec i32 1)) "#, snapshot: "../tests/unsupported-vec-literal.diag", }, DiagnosticCase { name: "array-return-type-mismatch", source: r#" (module main) (fn bad () -> (array i32 2) (array i32 1)) "#, snapshot: "../tests/array-return-type-mismatch.diag", }, DiagnosticCase { name: "array-argument-type-mismatch", source: r#" (module main) (fn first ((values (array i32 2))) -> i32 (index values 0)) (fn main () -> i32 (first (array i32 1))) "#, snapshot: "../tests/array-argument-type-mismatch.diag", }, DiagnosticCase { name: "array-local-initializer-type-mismatch", source: r#" (module main) (fn main () -> i32 (let values (array i32 2) (array i32 1)) 0) "#, snapshot: "../tests/array-local-initializer-type-mismatch.diag", }, DiagnosticCase { name: "malformed-option-constructor", source: r#" (module main) (fn bad () -> (option i32) (some i32)) "#, snapshot: "../tests/malformed-option-constructor.diag", }, DiagnosticCase { name: "option-constructor-type-mismatch", source: r#" (module main) (fn bad () -> (option i32) (some i32 true)) "#, snapshot: "../tests/option-constructor-type-mismatch.diag", }, DiagnosticCase { name: "unsupported-option-payload-type", source: r#" (module main) (fn main () -> i32 (some (vec i32) (std.vec.i32.empty))) "#, snapshot: "../tests/unsupported-option-payload-type.diag", }, DiagnosticCase { name: "unsupported-option-parameter-payload-type", source: r#" (module main) (fn take ((value (option (vec i32)))) -> i32 0) "#, snapshot: "../tests/unsupported-option-parameter-payload-type.diag", }, DiagnosticCase { name: "unsupported-option-return-payload-type", source: r#" (module main) (fn bad () -> (option (vec i32)) 0) "#, snapshot: "../tests/unsupported-option-return-payload-type.diag", }, DiagnosticCase { name: "malformed-result-constructor", source: r#" (module main) (fn bad () -> (result i32 i32) (ok i32 i32)) "#, snapshot: "../tests/malformed-result-constructor.diag", }, DiagnosticCase { name: "result-constructor-type-mismatch", source: r#" (module main) (fn bad () -> (result i32 i32) (err i32 i32 true)) "#, snapshot: "../tests/result-constructor-type-mismatch.diag", }, DiagnosticCase { name: "unsupported-result-payload-type", source: r#" (module main) (fn main () -> i32 (ok i32 bool true)) "#, snapshot: "../tests/unsupported-result-payload-type.diag", }, DiagnosticCase { name: "unsupported-result-string-bool", source: r#" (module main) (fn main () -> i32 (ok string bool "value")) "#, snapshot: "../tests/unsupported-result-string-bool.diag", }, DiagnosticCase { name: "unsupported-result-parameter-payload-type", source: r#" (module main) (fn take ((value (result i32 bool))) -> i32 0) "#, snapshot: "../tests/unsupported-result-parameter-payload-type.diag", }, DiagnosticCase { name: "unsupported-result-return-payload-type", source: r#" (module main) (fn bad () -> (result i32 bool) 0) "#, snapshot: "../tests/unsupported-result-return-payload-type.diag", }, DiagnosticCase { name: "unsupported-option-result-equality", source: r#" (module main) (fn main () -> i32 (if (= (some i32 1) (none i32)) 1 0)) "#, snapshot: "../tests/unsupported-option-result-equality.diag", }, DiagnosticCase { name: "unsupported-result-string-equality", source: r#" (module main) (fn main () -> i32 (if (= (ok string i32 "a") (err string i32 1)) 1 0)) "#, snapshot: "../tests/unsupported-result-string-equality.diag", }, DiagnosticCase { name: "unsupported-option-result-print", source: r#" (module main) (fn main () -> i32 (print_i32 (none i32)) 0) "#, snapshot: "../tests/unsupported-option-result-print.diag", }, DiagnosticCase { name: "unsupported-result-string-print", source: r#" (module main) (fn main () -> i32 (std.io.print_i32 (ok string i32 "a")) 0) "#, snapshot: "../tests/unsupported-result-string-print.diag", }, DiagnosticCase { name: "match-subject-type-mismatch", source: r#" (module main) (fn main () -> i32 (match 1 ((some payload) payload) ((none) 0))) "#, snapshot: "../tests/match-subject-type-mismatch.diag", }, DiagnosticCase { name: "unsupported-match-payload-type", source: r#" (module main) (fn main () -> i32 (match (some (vec i32) (std.vec.i32.empty)) ((some payload) payload) ((none) 0))) "#, snapshot: "../tests/unsupported-match-payload-type.diag", }, DiagnosticCase { name: "non-exhaustive-match", source: r#" (module main) (fn main ((value (option i32))) -> i32 (match value ((some payload) payload))) "#, snapshot: "../tests/non-exhaustive-match.diag", }, DiagnosticCase { name: "duplicate-match-arm", source: r#" (module main) (fn main ((value (option i32))) -> i32 (match value ((some payload) payload) ((some other) other) ((none) 0))) "#, snapshot: "../tests/duplicate-match-arm.diag", }, DiagnosticCase { name: "malformed-match-pattern", source: r#" (module main) (fn main ((value (option i32))) -> i32 (match value ((some) 1) ((none) 0))) "#, snapshot: "../tests/malformed-match-pattern.diag", }, DiagnosticCase { name: "match-arm-type-mismatch", source: r#" (module main) (fn main ((value (option i32))) -> i32 (match value ((some payload) payload) ((none) false))) "#, snapshot: "../tests/match-arm-type-mismatch.diag", }, DiagnosticCase { name: "match-binding-collision", source: r#" (module main) (fn main ((value (option i32)) (payload i32)) -> i32 (match value ((some payload) payload) ((none) 0))) "#, snapshot: "../tests/match-binding-collision.diag", }, DiagnosticCase { name: "unsupported-match-mutation", source: r#" (module main) (fn main ((value (option i32))) -> i32 (match (set value (none i32)) ((some payload) payload) ((none) 0))) "#, snapshot: "../tests/unsupported-match-mutation.diag", }, DiagnosticCase { name: "unsupported-match-container", source: r#" (module main) (fn main () -> i32 (match (array (option i32) (none i32)) ((some payload) payload) ((none) 0))) "#, snapshot: "../tests/unsupported-match-container.diag", }, DiagnosticCase { name: "option-observation-non-option", source: r#" (module main) (fn main () -> bool (is_some 1)) "#, snapshot: "../tests/option-observation-non-option.diag", }, DiagnosticCase { name: "result-observation-non-result", source: r#" (module main) (fn main () -> bool (is_ok 1)) "#, snapshot: "../tests/result-observation-non-result.diag", }, DiagnosticCase { name: "malformed-option-unwrap", source: r#" (module main) (fn main () -> i32 (unwrap_some)) "#, snapshot: "../tests/malformed-option-unwrap.diag", }, DiagnosticCase { name: "malformed-result-ok-unwrap", source: r#" (module main) (fn main () -> i32 (unwrap_ok)) "#, snapshot: "../tests/malformed-result-ok-unwrap.diag", }, DiagnosticCase { name: "malformed-result-err-unwrap", source: r#" (module main) (fn main () -> i32 (unwrap_err)) "#, snapshot: "../tests/malformed-result-err-unwrap.diag", }, DiagnosticCase { name: "option-unwrap-non-option", source: r#" (module main) (fn main () -> i32 (unwrap_some 1)) "#, snapshot: "../tests/option-unwrap-non-option.diag", }, DiagnosticCase { name: "result-ok-unwrap-non-result", source: r#" (module main) (fn main () -> i32 (unwrap_ok 1)) "#, snapshot: "../tests/result-ok-unwrap-non-result.diag", }, DiagnosticCase { name: "result-err-unwrap-non-result", source: r#" (module main) (fn main () -> i32 (unwrap_err 1)) "#, snapshot: "../tests/result-err-unwrap-non-result.diag", }, DiagnosticCase { name: "malformed-unsafe-form", source: r#" (module main) (fn main () -> i32 (unsafe)) "#, snapshot: "../tests/malformed-unsafe-form.diag", }, DiagnosticCase { name: "unsafe-required-operation", source: r#" (module main) (fn main () -> i32 (alloc i32)) "#, snapshot: "../tests/unsafe-required-operation.diag", }, DiagnosticCase { name: "unsupported-unsafe-operation", source: r#" (module main) (fn main () -> i32 (unsafe (alloc i32))) "#, snapshot: "../tests/unsupported-unsafe-operation.diag", }, DiagnosticCase { name: "unsafe-required-dealloc", source: unsafe_required_source!("dealloc"), snapshot: "../tests/unsafe-required-dealloc.diag", }, DiagnosticCase { name: "unsafe-required-load", source: unsafe_required_source!("load"), snapshot: "../tests/unsafe-required-load.diag", }, DiagnosticCase { name: "unsafe-required-store", source: unsafe_required_source!("store"), snapshot: "../tests/unsafe-required-store.diag", }, DiagnosticCase { name: "unsafe-required-ptr-add", source: unsafe_required_source!("ptr_add"), snapshot: "../tests/unsafe-required-ptr-add.diag", }, DiagnosticCase { name: "unsafe-required-unchecked-index", source: unsafe_required_source!("unchecked_index"), snapshot: "../tests/unsafe-required-unchecked-index.diag", }, DiagnosticCase { name: "unsafe-required-reinterpret", source: unsafe_required_source!("reinterpret"), snapshot: "../tests/unsafe-required-reinterpret.diag", }, DiagnosticCase { name: "unsafe-required-ffi-call", source: unsafe_required_source!("ffi_call"), snapshot: "../tests/unsafe-required-ffi-call.diag", }, DiagnosticCase { name: "unsupported-unsafe-dealloc", source: unsupported_unsafe_source!("dealloc"), snapshot: "../tests/unsupported-unsafe-dealloc.diag", }, DiagnosticCase { name: "unsupported-unsafe-load", source: unsupported_unsafe_source!("load"), snapshot: "../tests/unsupported-unsafe-load.diag", }, DiagnosticCase { name: "unsupported-unsafe-store", source: unsupported_unsafe_source!("store"), snapshot: "../tests/unsupported-unsafe-store.diag", }, DiagnosticCase { name: "unsupported-unsafe-ptr-add", source: unsupported_unsafe_source!("ptr_add"), snapshot: "../tests/unsupported-unsafe-ptr-add.diag", }, DiagnosticCase { name: "unsupported-unsafe-unchecked-index", source: unsupported_unsafe_source!("unchecked_index"), snapshot: "../tests/unsupported-unsafe-unchecked-index.diag", }, DiagnosticCase { name: "unsupported-unsafe-reinterpret", source: unsupported_unsafe_source!("reinterpret"), snapshot: "../tests/unsupported-unsafe-reinterpret.diag", }, DiagnosticCase { name: "unsupported-unsafe-ffi-call", source: unsupported_unsafe_source!("ffi_call"), snapshot: "../tests/unsupported-unsafe-ffi-call.diag", }, DiagnosticCase { name: "unsupported-struct-field-type", source: r#" (module main) (struct Point (x unit)) "#, snapshot: "../tests/unsupported-struct-field-type.diag", }, DiagnosticCase { name: "unsupported-primitive-struct-field-container", source: r#" (module main) (struct Matrix (rows (array (array i32 2) 2))) "#, snapshot: "../tests/unsupported-primitive-struct-field-container.diag", }, DiagnosticCase { name: "empty-struct", source: r#" (module main) (struct Empty) (fn main () -> i32 0) "#, snapshot: "../tests/empty-struct.diag", }, DiagnosticCase { name: "duplicate-struct", source: r#" (module main) (struct Point (x i32)) (struct Point (x i32)) (fn main () -> i32 0) "#, snapshot: "../tests/duplicate-struct.diag", }, DiagnosticCase { name: "duplicate-struct-field", source: r#" (module main) (struct Point (x i32) (x i32)) (fn main () -> i32 0) "#, snapshot: "../tests/duplicate-struct-field.diag", }, DiagnosticCase { name: "recursive-struct-field", source: r#" (module main) (struct Node (next Node)) (fn main () -> i32 0) "#, snapshot: "../tests/recursive-struct-field.diag", }, DiagnosticCase { name: "cyclic-struct-fields", source: r#" (module main) (struct Left (right Right)) (struct Right (left Left)) (fn main () -> i32 0) "#, snapshot: "../tests/cyclic-struct-fields.diag", }, DiagnosticCase { name: "struct-missing-field", source: r#" (module main) (struct Point (x i32) (y i32)) (fn main () -> i32 (. (Point (x 1)) x)) "#, snapshot: "../tests/struct-missing-field.diag", }, DiagnosticCase { name: "struct-unknown-field", source: r#" (module main) (struct Point (x i32) (y i32)) (fn main () -> i32 (. (Point (x 1) (z 2)) x)) "#, snapshot: "../tests/struct-unknown-field.diag", }, DiagnosticCase { name: "struct-field-order-mismatch", source: r#" (module main) (struct Point (x i32) (y i32)) (fn main () -> i32 (. (Point (y 2) (x 1)) x)) "#, snapshot: "../tests/struct-field-order-mismatch.diag", }, DiagnosticCase { name: "duplicate-struct-constructor-field", source: r#" (module main) (struct Point (x i32)) (fn main () -> i32 (. (Point (x 1) (x 2)) x)) "#, snapshot: "../tests/duplicate-struct-constructor-field.diag", }, DiagnosticCase { name: "field-access-on-non-struct", source: r#" (module main) (fn main () -> i32 (. 1 x)) "#, snapshot: "../tests/field-access-on-non-struct.diag", }, DiagnosticCase { name: "unknown-struct-local", source: r#" (module main) (fn main () -> i32 (let value Missing 0) 0) "#, snapshot: "../tests/unknown-struct-local.diag", }, DiagnosticCase { name: "unsupported-struct-field-mutation", source: r#" (module main) (struct Point (x i32)) (fn main () -> i32 (let p Point (Point (x 1))) (set (. p x) 2) (. p x)) "#, snapshot: "../tests/unsupported-struct-field-mutation.diag", }, DiagnosticCase { name: "duplicate-local", source: r#" (module main) (fn main () -> i32 (let x i32 1) (var x i32 2) x) "#, snapshot: "../tests/duplicate-local.diag", }, DiagnosticCase { name: "local-redeclares-parameter", source: r#" (module main) (fn id ((value i32)) -> i32 (let value i32 1) value) "#, snapshot: "../tests/local-redeclares-parameter.diag", }, DiagnosticCase { name: "local-shadows-function", source: r#" (module main) (fn helper () -> i32 1) (fn main () -> i32 (let helper i32 2) helper) "#, snapshot: "../tests/local-shadows-function.diag", }, DiagnosticCase { name: "local-shadows-intrinsic", source: r#" (module main) (fn main () -> i32 (let print_i32 i32 1) print_i32) "#, snapshot: "../tests/local-shadows-intrinsic.diag", }, DiagnosticCase { name: "unsupported-local-type", source: r#" (module main) (fn main () -> i32 (let ignored unit (print_i32 1)) 0) "#, snapshot: "../tests/unsupported-local-type.diag", }, DiagnosticCase { name: "single-file-main-i64-return", source: r#" (module main) (fn main () -> i64 1i64) "#, snapshot: "../tests/single-file-main-i64-return.diag", }, DiagnosticCase { name: "set-unknown-local", source: r#" (module main) (fn main () -> i32 (set missing 1) 0) "#, snapshot: "../tests/set-unknown-local.diag", }, DiagnosticCase { name: "set-parameter", source: r#" (module main) (fn id ((value i32)) -> i32 (set value 1) value) "#, snapshot: "../tests/set-parameter.diag", }, DiagnosticCase { name: "set-immutable-local", source: r#" (module main) (fn main () -> i32 (let x i32 1) (set x 2) x) "#, snapshot: "../tests/set-immutable-local.diag", }, DiagnosticCase { name: "set-type-mismatch", source: r#" (module main) (fn main () -> i32 (var x i32 1) (set x true) x) "#, snapshot: "../tests/set-type-mismatch.diag", }, DiagnosticCase { name: "nested-local-declaration", source: r#" (module main) (fn main () -> i32 (+ (let x i32 1) 2)) "#, snapshot: "../tests/nested-local-declaration.diag", }, DiagnosticCase { name: "malformed-if", source: r#" (module main) (fn main () -> i32 (if true 1) ) "#, snapshot: "../tests/malformed-if.diag", }, DiagnosticCase { name: "if-condition-not-bool", source: r#" (module main) (fn main () -> i32 (if 1 2 3)) "#, snapshot: "../tests/if-condition-not-bool.diag", }, DiagnosticCase { name: "if-branch-type-mismatch", source: r#" (module main) (fn main () -> i32 (if true 1 false)) "#, snapshot: "../tests/if-branch-type-mismatch.diag", }, DiagnosticCase { name: "malformed-while", source: r#" (module main) (fn main () -> i32 (while) 0) "#, snapshot: "../tests/malformed-while.diag", }, DiagnosticCase { name: "empty-while-body", source: r#" (module main) (fn main () -> i32 (while true) 0) "#, snapshot: "../tests/empty-while-body.diag", }, DiagnosticCase { name: "while-condition-not-bool", source: r#" (module main) (fn main () -> i32 (while 1 (print_i32 1)) 0) "#, snapshot: "../tests/while-condition-not-bool.diag", }, DiagnosticCase { name: "while-body-local", source: r#" (module main) (fn main () -> i32 (while true (let x i32 1)) 0) "#, snapshot: "../tests/while-body-local.diag", }, DiagnosticCase { name: "while-body-non-unit", source: r#" (module main) (fn main () -> i32 (while true 1) 0) "#, snapshot: "../tests/while-body-non-unit.diag", }, DiagnosticCase { name: "nested-while", source: r#" (module main) (fn main () -> i32 (while true (while false (print_i32 1))) 0) "#, snapshot: "../tests/nested-while.diag", }, DiagnosticCase { name: "while-final-function", source: r#" (module main) (fn main () -> i32 (while false (print_i32 1)) ) "#, snapshot: "../tests/while-final-function.diag", }, DiagnosticCase { name: "while-final-test", source: r#" (module main) (test "loop final" (var i i32 0) (while false (set i 1))) "#, snapshot: "../tests/while-final-test.diag", }, ]; #[test] fn current_negative_cases_match_machine_diagnostic_snapshots() { for case in CASES { let output = run_compiler(case.name, case.source); let stdout = String::from_utf8_lossy(&output.stdout); let stderr = String::from_utf8_lossy(&output.stderr); assert!( !output.status.success(), "compiler unexpectedly accepted fixture `{}`\nstdout:\n{}\nstderr:\n{}", case.name, stdout, stderr, ); assert!( stdout.is_empty(), "compiler emitted stdout for rejected fixture `{}`\nstdout:\n{}\nstderr:\n{}", case.name, stdout, stderr, ); let actual = normalize_fixture_path(&machine_diagnostic(&stderr)); let expected = fs::read_to_string(case.snapshot) .unwrap_or_else(|err| panic!("read `{}`: {}", case.snapshot, err)); assert_eq!( expected, actual, "machine diagnostic snapshot mismatch for `{}`", case.name ); } } struct DiagnosticCase { name: &'static str, source: &'static str, snapshot: &'static str, } fn run_compiler(name: &str, source: &str) -> Output { let compiler = env!("CARGO_BIN_EXE_glagol"); let fixture = write_fixture(name, source); Command::new(compiler) .arg(&fixture) .output() .unwrap_or_else(|err| panic!("run glagol on `{}`: {}", fixture.display(), err)) } fn write_fixture(name: &str, source: &str) -> PathBuf { let mut path = std::env::temp_dir(); let id = NEXT_FIXTURE_ID.fetch_add(1, Ordering::Relaxed); path.push(format!( "glagol-diagnostics-contract-{}-{}-{}.slo", std::process::id(), id, name )); fs::write(&path, source).unwrap_or_else(|err| panic!("write `{}`: {}", path.display(), err)); path } fn machine_diagnostic(stderr: &str) -> String { let mut diagnostics = Vec::new(); let mut current = Vec::new(); let mut in_machine_diagnostic = false; let mut depth = 0; for line in stderr.lines() { if line == "(diagnostic" { in_machine_diagnostic = true; current.clear(); depth = 0; } if in_machine_diagnostic { current.push(line); depth += paren_delta(line); } if in_machine_diagnostic && depth == 0 { diagnostics.push(current.join("\n")); current.clear(); in_machine_diagnostic = false; } } assert!( !diagnostics.is_empty(), "stderr did not contain a machine diagnostic:\n{}", stderr ); diagnostics.join("\n\n") + "\n" } fn paren_delta(line: &str) -> isize { let mut delta = 0; let mut in_string = false; let mut escaped = false; for ch in line.chars() { if in_string { if escaped { escaped = false; } else if ch == '\\' { escaped = true; } else if ch == '"' { in_string = false; } } else if ch == '"' { in_string = true; } else if ch == '(' { delta += 1; } else if ch == ')' { delta -= 1; } } delta } fn normalize_fixture_path(diagnostic: &str) -> String { diagnostic .lines() .map(|line| { let trimmed = line.trim_start(); if trimmed.starts_with("(file ") { format!( "{}(file \"\")", " ".repeat(line.len() - trimmed.len()) ) } else { line.to_string() } }) .collect::>() .join("\n") + "\n" }