diff --git a/crates/emmylua_code_analysis/src/diagnostic/checker/cast_type_mismatch.rs b/crates/emmylua_code_analysis/src/diagnostic/checker/cast_type_mismatch.rs index 274a8fdf8..fb529deb7 100644 --- a/crates/emmylua_code_analysis/src/diagnostic/checker/cast_type_mismatch.rs +++ b/crates/emmylua_code_analysis/src/diagnostic/checker/cast_type_mismatch.rs @@ -70,7 +70,7 @@ fn check_cast_compatibility( return Some(()); } - // 检查是否可以从原始类型转换为目标类型 + // 检查是否可以从原始类型转换为目标类型, 允许父类转为子类 let result = match origin_type { LuaType::Union(union_type) => { for member_type in union_type.into_vec() { @@ -137,6 +137,7 @@ fn add_cast_type_mismatch_diagnostic( } } +/// 允许父类转为子类 fn cast_type_check( semantic_model: &SemanticModel, origin_type: &LuaType, @@ -197,8 +198,13 @@ fn cast_type_check( } else if origin_type.is_number() && target_type.is_number() { return Ok(()); } - - semantic_model.type_check_detail(target_type, origin_type) + match semantic_model.type_check_detail(target_type, origin_type) { + Ok(_) => Ok(()), + Err(_) => match semantic_model.type_check_detail(origin_type, target_type) { + Ok(_) => Ok(()), + Err(reason) => Err(reason), + }, + } } } } diff --git a/crates/emmylua_code_analysis/src/diagnostic/test/param_type_check_test.rs b/crates/emmylua_code_analysis/src/diagnostic/test/param_type_check_test.rs index 3a096f71c..391da97f9 100644 --- a/crates/emmylua_code_analysis/src/diagnostic/test/param_type_check_test.rs +++ b/crates/emmylua_code_analysis/src/diagnostic/test/param_type_check_test.rs @@ -1308,4 +1308,30 @@ mod test { "# )); } + + #[test] + fn test_self_contain_tpl() { + let mut ws = VirtualWorkspace::new(); + ws.def_file( + "test.lua", + r#" + ---@class Observable + Observable = {} + + ---@param ... Observable + function zip(...) + end + + "#, + ); + + assert!(ws.check_code_for_namespace( + DiagnosticCode::ParamTypeNotMatch, + r#" + function Observable:test() + zip(self) + end + "# + )); + } } diff --git a/crates/emmylua_code_analysis/src/semantic/type_check/generic_type.rs b/crates/emmylua_code_analysis/src/semantic/type_check/generic_type.rs index 0b18ac70e..a021471ae 100644 --- a/crates/emmylua_code_analysis/src/semantic/type_check/generic_type.rs +++ b/crates/emmylua_code_analysis/src/semantic/type_check/generic_type.rs @@ -284,5 +284,15 @@ fn check_generic_type_compact_ref_type( } } + // 如果泛型参数是`any`, 那么我们只需要匹配基础类型 + if source_generic.get_params().iter().any(|p| p.is_any()) { + return check_general_type_compact( + context, + &source_generic.get_base_type(), + &LuaType::Ref(ref_id.clone()), + check_guard.next_level()?, + ); + } + Err(TypeCheckFailReason::TypeNotMatch) }