use super::*;
#[test]
fn test_inference_context_new() {
let ctx = InferenceContext::new();
drop(ctx);
}
#[test]
fn test_inference_context_with_env() {
let env = TypeEnv::standard();
let ctx = InferenceContext::with_env(env);
drop(ctx);
}
#[test]
fn test_instantiate_mono_type() {
let mut ctx = InferenceContext::new();
let scheme = TypeScheme::mono(MonoType::Int);
let instantiated = ctx.instantiate(&scheme);
assert!(matches!(instantiated, MonoType::Int));
}
#[test]
fn test_instantiate_poly_type() {
let mut ctx = InferenceContext::new();
let var = TyVar(0);
let scheme = TypeScheme {
vars: vec![var.clone()],
ty: MonoType::Var(var),
};
let instantiated = ctx.instantiate(&scheme);
assert!(matches!(instantiated, MonoType::Var(_)));
}
#[test]
fn test_infer_integer_literal() {
let mut ctx = InferenceContext::new();
let expr = parse_code("42");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_float_literal() {
let mut ctx = InferenceContext::new();
let expr = parse_code("3.14");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Float));
}
#[test]
fn test_infer_string_literal() {
let mut ctx = InferenceContext::new();
let expr = parse_code("\"hello\"");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::String));
}
#[test]
fn test_infer_bool_literal_true() {
let mut ctx = InferenceContext::new();
let expr = parse_code("true");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_bool_literal_false() {
let mut ctx = InferenceContext::new();
let expr = parse_code("false");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_addition_int() {
let mut ctx = InferenceContext::new();
let expr = parse_code("1 + 2");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_string_concatenation() {
let mut ctx = InferenceContext::new();
let expr = parse_code("\"hello\" + \"world\"");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::String));
}
#[test]
fn test_infer_subtraction() {
let mut ctx = InferenceContext::new();
let expr = parse_code("5 - 3");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_multiplication() {
let mut ctx = InferenceContext::new();
let expr = parse_code("4 * 2");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_division() {
let mut ctx = InferenceContext::new();
let expr = parse_code("10 / 2");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_modulo() {
let mut ctx = InferenceContext::new();
let expr = parse_code("10 % 3");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_power() {
let mut ctx = InferenceContext::new();
let expr = parse_code("2 ** 3");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_comparison_equal() {
let mut ctx = InferenceContext::new();
let expr = parse_code("1 == 2");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_comparison_not_equal() {
let mut ctx = InferenceContext::new();
let expr = parse_code("1 != 2");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_comparison_less() {
let mut ctx = InferenceContext::new();
let expr = parse_code("1 < 2");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_comparison_less_equal() {
let mut ctx = InferenceContext::new();
let expr = parse_code("1 <= 2");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_comparison_greater() {
let mut ctx = InferenceContext::new();
let expr = parse_code("2 > 1");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_comparison_greater_equal() {
let mut ctx = InferenceContext::new();
let expr = parse_code("2 >= 1");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_logical_and() {
let mut ctx = InferenceContext::new();
let expr = parse_code("true && false");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_logical_or() {
let mut ctx = InferenceContext::new();
let expr = parse_code("true || false");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_bitwise_and() {
let mut ctx = InferenceContext::new();
let expr = parse_code("5 & 3");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_bitwise_or() {
let mut ctx = InferenceContext::new();
let expr = parse_code("5 | 3");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_bitwise_xor() {
let mut ctx = InferenceContext::new();
let expr = parse_code("5 ^ 3");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_left_shift() {
let mut ctx = InferenceContext::new();
let expr = parse_code("1 << 4");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_right_shift() {
let mut ctx = InferenceContext::new();
let expr = parse_code("16 >> 2");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_unary_not() {
let mut ctx = InferenceContext::new();
let expr = parse_code("!true");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_unary_negate() {
let mut ctx = InferenceContext::new();
let expr = parse_code("-42");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_empty_list() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[]");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::List(_)));
}
#[test]
fn test_infer_int_list() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2, 3]");
let ty = ctx.infer(&expr).expect("should infer");
match ty {
MonoType::List(elem_ty) => assert!(matches!(*elem_ty, MonoType::Int)),
_ => panic!("Expected List type"),
}
}
#[test]
fn test_infer_string_list() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[\"a\", \"b\", \"c\"]");
let ty = ctx.infer(&expr).expect("should infer");
match ty {
MonoType::List(elem_ty) => assert!(matches!(*elem_ty, MonoType::String)),
_ => panic!("Expected List type"),
}
}
#[test]
fn test_infer_tuple() {
let mut ctx = InferenceContext::new();
let expr = parse_code("(1, \"hello\", true)");
let ty = ctx.infer(&expr).expect("should infer");
match ty {
MonoType::Tuple(elems) => {
assert_eq!(elems.len(), 3);
assert!(matches!(elems[0], MonoType::Int));
assert!(matches!(elems[1], MonoType::String));
assert!(matches!(elems[2], MonoType::Bool));
}
_ => panic!("Expected Tuple type"),
}
}
#[test]
fn test_infer_if_with_else() {
let mut ctx = InferenceContext::new();
let expr = parse_code("if true { 1 } else { 2 }");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_if_without_else() {
let mut ctx = InferenceContext::new();
let expr = parse_code("if true { 1 }");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_infer_empty_block() {
let mut ctx = InferenceContext::new();
let expr = parse_code("{ 1 }");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_block_with_expressions() {
let mut ctx = InferenceContext::new();
let expr = parse_code("{ 1; 2; 3 }");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_range() {
let mut ctx = InferenceContext::new();
let expr = parse_code("0..10");
let ty = ctx.infer(&expr).expect("should infer");
match ty {
MonoType::List(elem_ty) => assert!(matches!(*elem_ty, MonoType::Int)),
_ => panic!("Expected List<Int> for range"),
}
}
#[test]
fn test_infer_simple_lambda() {
let mut ctx = InferenceContext::new();
let expr = parse_code("|x| x");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Function(_, _)));
}
#[test]
fn test_infer_lambda_with_body() {
let mut ctx = InferenceContext::new();
let expr = parse_code("|x, y| x + y");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Function(_, _)));
}
#[test]
fn test_infer_function_definition() {
let mut ctx = InferenceContext::new();
let expr = parse_code("fun add(x, y) { x + y }");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_infer_match_simple() {
let mut ctx = InferenceContext::new();
let expr = parse_code("match 1 { 1 => true, _ => false }");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_for_loop() {
let mut ctx = InferenceContext::new();
let expr = parse_code("for x in [1, 2, 3] { x }");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Unit));
}
#[test]
fn test_infer_while_loop() {
let mut ctx = InferenceContext::new();
let expr = parse_code("while true { 1 }");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_type_constraint_unify_debug() {
let constraint = TypeConstraint::Unify(MonoType::Int, MonoType::Int);
let debug_str = format!("{constraint:?}");
assert!(debug_str.contains("Unify"));
}
#[test]
fn test_type_constraint_function_arity_debug() {
let func_ty = MonoType::Function(Box::new(MonoType::Int), Box::new(MonoType::Int));
let constraint = TypeConstraint::FunctionArity(func_ty, 1);
let debug_str = format!("{constraint:?}");
assert!(debug_str.contains("FunctionArity"));
}
#[test]
fn test_type_constraint_method_call_debug() {
let constraint =
TypeConstraint::MethodCall(MonoType::String, "len".to_string(), Vec::new());
let debug_str = format!("{constraint:?}");
assert!(debug_str.contains("MethodCall"));
}
#[test]
fn test_type_constraint_iterable_debug() {
let constraint =
TypeConstraint::Iterable(MonoType::List(Box::new(MonoType::Int)), MonoType::Int);
let debug_str = format!("{constraint:?}");
assert!(debug_str.contains("Iterable"));
}
#[test]
fn test_type_constraint_clone() {
let constraint = TypeConstraint::Unify(MonoType::Int, MonoType::Float);
let cloned = constraint.clone();
match cloned {
TypeConstraint::Unify(t1, t2) => {
assert!(matches!(t1, MonoType::Int));
assert!(matches!(t2, MonoType::Float));
}
_ => panic!("Expected Unify constraint"),
}
}
#[test]
fn test_infer_list_len_method() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2, 3].len()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_string_len_method() {
let mut ctx = InferenceContext::new();
let expr = parse_code("\"hello\".len()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_string_chars_method() {
let mut ctx = InferenceContext::new();
let expr = parse_code("\"hello\".chars()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::List(_)));
}
#[test]
fn test_recursion_limit_check() {
let mut ctx = InferenceContext::new();
let expr = parse_code("((((1))))");
let result = ctx.infer(&expr);
assert!(result.is_ok());
}
#[test]
fn test_infer_undefined_variable_error() {
let mut ctx = InferenceContext::new();
let expr = parse_code("undefined_var");
let result = ctx.infer(&expr);
assert!(result.is_err());
let err = result.unwrap_err().to_string();
assert!(err.contains("Undefined"));
}
#[test]
fn test_infer_type_mismatch_logical_op() {
let mut ctx = InferenceContext::new();
let expr = parse_code("1 && 2");
let result = ctx.infer(&expr);
assert!(result.is_err());
}
#[test]
fn test_infer_list_comprehension() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[x * 2 for x in [1, 2, 3]]");
let ty = ctx.infer(&expr).expect("should infer");
match ty {
MonoType::List(elem_ty) => assert!(matches!(*elem_ty, MonoType::Int)),
_ => panic!("Expected List type"),
}
}
#[test]
fn test_infer_list_comprehension_with_condition() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[x for x in [1, 2, 3] if x > 1]");
let ty = ctx.infer(&expr).expect("should infer");
match ty {
MonoType::List(elem_ty) => assert!(matches!(*elem_ty, MonoType::Int)),
_ => panic!("Expected List type"),
}
}
#[test]
fn test_infer_null_coalesce() {
let mut ctx = InferenceContext::new();
let expr = parse_code("1 ?? 0");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_nested_binary_ops() {
let mut ctx = InferenceContext::new();
let expr = parse_code("1 + 2 * 3 - 4 / 2");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_chained_comparisons() {
let mut ctx = InferenceContext::new();
let expr = parse_code("(1 < 2) && (2 < 3)");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Bool));
}
#[test]
fn test_infer_match_with_literal_patterns() {
let mut ctx = InferenceContext::new();
let expr = parse_code("match 42 { 0 => \"zero\", _ => \"other\" }");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::String));
}
#[test]
fn test_infer_match_with_wildcard() {
let mut ctx = InferenceContext::new();
let expr = parse_code("match true { _ => 0 }");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_conditional() {
let mut ctx = InferenceContext::new();
let expr = parse_code("if true { 1 } else { 2 }");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_list_contains() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2, 3].len()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_struct_literal() {
let mut ctx = InferenceContext::new();
let expr = parse_code("Point { x: 1, y: 2 }");
let ty = ctx.infer(&expr).expect("should infer");
match ty {
MonoType::Named(name) => assert_eq!(name, "Point"),
_ => panic!("Expected Named type"),
}
}
#[test]
fn test_infer_throw() {
let mut ctx = InferenceContext::new();
let expr = parse_code("throw \"error\"");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Var(_)));
}
#[test]
fn test_infer_await() {
let mut ctx = InferenceContext::new();
let expr = parse_code("await 42");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Var(_)));
}
#[test]
fn test_infer_break() {
let mut ctx = InferenceContext::new();
let expr = parse_code("break");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Unit | MonoType::Var(_)));
}
#[test]
fn test_infer_continue() {
let mut ctx = InferenceContext::new();
let expr = parse_code("continue");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Unit | MonoType::Var(_)));
}
#[test]
fn test_infer_return_value() {
let mut ctx = InferenceContext::new();
let expr = parse_code("return 42");
let result = ctx.infer(&expr);
if let Ok(ty) = result {
assert!(matches!(
ty,
MonoType::Int | MonoType::Var(_) | MonoType::Unit
));
}
}
#[test]
fn test_infer_loop_expression() {
let mut ctx = InferenceContext::new();
let expr = parse_code("loop { break }");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Unit));
}
#[test]
fn test_infer_index_access() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2, 3][0]");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Int));
}
#[test]
fn test_infer_field_access() {
let mut ctx = InferenceContext::new();
let expr = parse_code("Point { x: 1, y: 2 }.x");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Var(_) | MonoType::Int));
}
#[test]
fn test_infer_assignment() {
let mut ctx = InferenceContext::new();
let expr = parse_code("let x = 42");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_infer_vec_macro_empty() {
let mut ctx = InferenceContext::new();
let expr = parse_code("vec![]");
let result = ctx.infer(&expr);
if let Ok(ty) = result {
assert!(matches!(ty, MonoType::List(_)));
}
}
#[test]
fn test_infer_vec_macro_with_elements() {
let mut ctx = InferenceContext::new();
let expr = parse_code("vec![1, 2, 3]");
let result = ctx.infer(&expr);
if let Ok(ty) = result {
assert!(matches!(ty, MonoType::List(_)));
}
}
#[test]
fn test_infer_dataframe_filter_method() {
let mut ctx = InferenceContext::new();
let code = "df.filter(true)";
let expr = parse_code(code);
let result = ctx.infer(&expr);
if result.is_err() {
assert!(result.unwrap_err().to_string().contains("Undefined"));
}
}
#[test]
fn test_infer_series_mean_method() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1.0, 2.0, 3.0].sum()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Float));
}
#[test]
fn test_infer_list_pop_returns_optional() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2, 3].pop()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Optional(_)));
}
#[test]
fn test_infer_list_min_returns_optional() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2, 3].min()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Optional(_)));
}
#[test]
fn test_infer_list_max_returns_optional() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2, 3].max()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Optional(_)));
}
#[test]
fn test_infer_list_sorted() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[3, 1, 2].sorted()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::List(_)));
}
#[test]
fn test_infer_list_reversed() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2, 3].reversed()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::List(_)));
}
#[test]
fn test_infer_list_unique() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2, 2, 3].unique()");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::List(_)));
}
#[test]
fn test_infer_list_push() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2].push(3)");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Unit));
}
#[test]
fn test_infer_method_wrong_args_count() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2, 3].len(42)");
let result = ctx.infer(&expr);
assert!(result.is_err());
}
#[test]
fn test_infer_push_wrong_args_count() {
let mut ctx = InferenceContext::new();
let expr = parse_code("[1, 2].push()");
let result = ctx.infer(&expr);
assert!(result.is_err());
}
#[test]
fn test_infer_reference() {
let mut ctx = InferenceContext::new();
let expr = parse_code("&42");
let ty = ctx.infer(&expr).expect("should infer");
assert!(matches!(ty, MonoType::Reference(_)));
}
#[test]
fn test_infer_as_cast() {
let mut ctx = InferenceContext::new();
let expr = parse_code("42 as Float");
let result = ctx.infer(&expr);
if let Ok(ty) = result {
assert!(matches!(ty, MonoType::Float | MonoType::Var(_)));
}
}
#[test]
fn test_infer_string_interpolation() {
let mut ctx = InferenceContext::new();
let expr = parse_code("\"hello {42}\"");
let result = ctx.infer(&expr);
if let Ok(ty) = result {
assert!(matches!(ty, MonoType::String));
}
}
#[test]
fn test_infer_ok_value() {
let mut ctx = InferenceContext::new();
let expr = parse_code("Ok(42)");
let result = ctx.infer(&expr);
if let Ok(ty) = result {
assert!(matches!(ty, MonoType::Result(_, _) | MonoType::Named(_)));
}
}
#[test]
fn test_infer_err_value() {
let mut ctx = InferenceContext::new();
let expr = parse_code("Err(\"error\")");
let result = ctx.infer(&expr);
if let Ok(ty) = result {
assert!(matches!(ty, MonoType::Result(_, _) | MonoType::Named(_)));
}
}
#[test]
fn test_infer_some_value() {
let mut ctx = InferenceContext::new();
let expr = parse_code("Some(42)");
let result = ctx.infer(&expr);
if let Ok(ty) = result {
assert!(matches!(ty, MonoType::Optional(_) | MonoType::Named(_)));
}
}
#[test]
fn test_infer_none_value() {
let mut ctx = InferenceContext::new();
let expr = parse_code("None");
let result = ctx.infer(&expr);
if let Ok(ty) = result {
assert!(matches!(
ty,
MonoType::Optional(_) | MonoType::Named(_) | MonoType::Var(_)
));
}
}
#[test]
fn test_infer_async_block() {
let mut ctx = InferenceContext::new();
let expr = parse_code("async { 42 }");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_infer_add_assign() {
let mut ctx = InferenceContext::new();
let expr = parse_code("let mut x = 1; x += 2");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_infer_sub_assign() {
let mut ctx = InferenceContext::new();
let expr = parse_code("let mut x = 5; x -= 3");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_infer_mul_assign() {
let mut ctx = InferenceContext::new();
let expr = parse_code("let mut x = 2; x *= 3");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_infer_pre_increment() {
let mut ctx = InferenceContext::new();
let expr = parse_code("let mut x = 1; ++x");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_infer_post_increment() {
let mut ctx = InferenceContext::new();
let expr = parse_code("let mut x = 1; x++");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_infer_pre_decrement() {
let mut ctx = InferenceContext::new();
let expr = parse_code("let mut x = 5; --x");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}
#[test]
fn test_infer_post_decrement() {
let mut ctx = InferenceContext::new();
let expr = parse_code("let mut x = 5; x--");
let result = ctx.infer(&expr);
assert!(result.is_ok() || result.is_err());
}