diff --git a/kclvm/sema/src/resolver/test_fail_data/lambda_ty_error.k b/kclvm/sema/src/resolver/test_fail_data/lambda_ty_error.k new file mode 100644 index 000000000..e07633419 --- /dev/null +++ b/kclvm/sema/src/resolver/test_fail_data/lambda_ty_error.k @@ -0,0 +1,6 @@ +_func = lambda x: int, y: int -> int { + x - y +} # Ok +_func = lambda x: int, y: int -> str { + str(x + y) +} # Error: expect function (int, int) -> str, got function (int, int) -> int \ No newline at end of file diff --git a/kclvm/sema/src/resolver/tests.rs b/kclvm/sema/src/resolver/tests.rs index 84f5c2592..807500310 100644 --- a/kclvm/sema/src/resolver/tests.rs +++ b/kclvm/sema/src/resolver/tests.rs @@ -549,3 +549,23 @@ fn test_resolve_assignment_in_lambda() { let images_scope_obj = lambda_scope.borrow().elems.get("images").unwrap().clone(); assert_eq!(images_scope_obj.borrow().ty.ty_str(), "[str]"); } + +#[test] +fn test_resolve_lambda_assignment_diagnostic() { + let sess = Arc::new(ParseSession::default()); + let mut program = load_program( + sess.clone(), + &["./src/resolver/test_fail_data/lambda_ty_error.k"], + None, + ) + .unwrap(); + let scope = resolve_program(&mut program); + assert_eq!(scope.handler.diagnostics.len(), 1); + let diag = &scope.handler.diagnostics[0]; + assert_eq!(diag.code, Some(DiagnosticId::Error(ErrorKind::TypeError))); + assert_eq!(diag.messages.len(), 1); + assert_eq!( + diag.messages[0].message, + "expected function (int, int) -> int, got function (int, int) -> str" + ); +} diff --git a/kclvm/sema/src/ty/mod.rs b/kclvm/sema/src/ty/mod.rs index 81832505e..30221f1df 100644 --- a/kclvm/sema/src/ty/mod.rs +++ b/kclvm/sema/src/ty/mod.rs @@ -80,7 +80,7 @@ impl Type { .join("|"), TypeKind::Schema(schema_ty) => schema_ty.name.to_string(), TypeKind::NumberMultiplier(number_multiplier) => number_multiplier.ty_str(), - TypeKind::Function(_) => FUNCTION_TYPE_STR.to_string(), + TypeKind::Function(func_ty) => func_ty.ty_str(), TypeKind::Void => VOID_TYPE_STR.to_string(), TypeKind::Module(module_ty) => format!("{} '{}'", MODULE_TYPE_STR, module_ty.pkgpath), TypeKind::Named(name) => name.to_string(), @@ -387,6 +387,20 @@ pub struct FunctionType { pub kw_only_index: Option, } +impl FunctionType { + pub fn ty_str(&self) -> String { + format!( + "function ({}) -> {}", + self.params + .iter() + .map(|param| param.ty.ty_str()) + .collect::>() + .join(", "), + self.return_ty.ty_str() + ) + } +} + impl FunctionType { #[inline] pub fn variadic_func() -> Self {