feat: implement effect inference

Add automatic effect inference for functions and lambdas that don't
explicitly declare their effects. The implementation:

- Tracks inferred effects during type checking via `inferred_effects`
- Uses `inferring_effects` flag to switch between validation and inference
- Functions without explicit `with {Effects}` have their effects inferred
- Lambda expressions also support effect inference
- When effects are explicitly declared, validates that inferred effects
  are a subset of declared effects
- Pure functions are checked against both declared and inferred effects

This makes the effect system more ergonomic by not requiring explicit
effect annotations for every function while still maintaining safety.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 04:58:49 -05:00
parent 05a85ea27f
commit 6f860a435b
2 changed files with 127 additions and 16 deletions

View File

@@ -1376,5 +1376,48 @@ c")"#;
let result = eval(source);
assert!(result.is_ok(), "Expected success but got: {:?}", result);
}
#[test]
fn test_effect_inference_function() {
// Test that effects are inferred when not explicitly declared
// This function uses Console effect without declaring it
let source = r#"
effect Console {
fn print(msg: String): Unit
}
fn greet(name: String): Unit = Console.print("Hello")
let result = 42
"#;
let result = eval(source);
assert!(result.is_ok(), "Expected success with inferred effects but got: {:?}", result);
}
#[test]
fn test_effect_inference_lambda() {
// Test that lambda effects are inferred
let source = r#"
effect Logger {
fn log(msg: String): Unit
}
let logFn = fn(msg: String) => Logger.log(msg)
let result = 42
"#;
let result = eval(source);
assert!(result.is_ok(), "Expected success with inferred lambda effects but got: {:?}", result);
}
#[test]
fn test_explicit_effects_validation() {
// Test that explicitly declared effects are validated against usage
let source = r#"
effect Console {
fn print(msg: String): Unit
}
fn greet(name: String): Unit with {Console} = Console.print("Hello")
let result = 42
"#;
let result = eval(source);
assert!(result.is_ok(), "Expected success with explicit effects but got: {:?}", result);
}
}
}