diff --git a/src/analyzer/mod.rs b/src/analyzer/mod.rs index 76ca108..08f2289 100644 --- a/src/analyzer/mod.rs +++ b/src/analyzer/mod.rs @@ -1030,8 +1030,18 @@ impl Analyzer { )); } } + Statement::Return(None, span) => { + // Bare `return` in a function with a declared return + // type is an error — the caller expects a value. + if self.in_function_body && self.current_return_type.is_some() { + self.diagnostics.push(Diagnostic::error( + ErrorCode::E0203, + "missing return value in function with declared return type", + *span, + )); + } + } Statement::WaitFrame(_) - | Statement::Return(None, _) | Statement::LoadBackground(_, _) | Statement::SetPalette(_, _) => {} Statement::DebugLog(args, _) => { diff --git a/src/analyzer/tests.rs b/src/analyzer/tests.rs index a4932a4..a8c1134 100644 --- a/src/analyzer/tests.rs +++ b/src/analyzer/tests.rs @@ -601,6 +601,26 @@ fn analyze_loop_with_break_ok() { ); } +#[test] +fn analyze_bare_return_from_typed_fn_errors() { + // A `return` with no value inside a function that has a declared + // return type should produce E0203. + let errors = analyze_errors( + r#" + game "Test" { mapper: NROM } + fun get_five() -> u8 { + return + } + on frame { wait_frame } + start Main + "#, + ); + assert!( + errors.contains(&ErrorCode::E0203), + "bare return from typed fn should produce E0203, got: {errors:?}" + ); +} + #[test] fn analyze_return_value_from_void_fn() { let errors = analyze_errors(