use lex_syntax::parse_source;
fn assert_parses(src: &str) {
parse_source(src).unwrap_or_else(|e| panic!("expected to parse, got {e}\n--- src ---\n{src}"));
}
#[test]
fn fn_name_can_start_with_underscore() {
assert_parses("fn _host(x :: Int) -> Int { x + 1 }\n");
}
#[test]
fn fn_param_can_start_with_underscore() {
assert_parses("fn id(_unused :: Int, y :: Int) -> Int { y }\n");
}
#[test]
fn let_binding_name_can_start_with_underscore() {
assert_parses("fn main() -> Int { let _seen := 1\n_seen }\n");
}
#[test]
fn let_underscore_discards_value() {
assert_parses("fn main() -> Int { let _ := 1 + 2\n42 }\n");
}
#[test]
fn multiple_let_underscore_in_sequence() {
assert_parses("fn main() -> Int {\n let _ := 1\n let _ := 2\n let _ := 3\n 42\n}\n");
}
#[test]
fn underscore_alone_is_not_an_identifier() {
let r = parse_source("fn _(x :: Int) -> Int { x }\n");
assert!(r.is_err(), "bare `_` is not a valid fn name");
}
#[test]
fn double_underscore_identifier() {
assert_parses("fn __helper(x :: Int) -> Int { x }\n");
assert_parses("fn user(__opaque :: Int) -> Int { __opaque + 1 }\n");
}
#[test]
fn underscore_match_arm_pattern_still_works() {
assert_parses("fn classify(n :: Int) -> Int {\n match n {\n 0 => 0,\n _ => 1,\n }\n}\n");
}