Skip to content

Commit 7184825

Browse files
committed
fix(diagnostic): resolve alias types before assign mismatch checks
1 parent 0a01b57 commit 7184825

2 files changed

Lines changed: 53 additions & 4 deletions

File tree

crates/emmylua_code_analysis/src/diagnostic/checker/assign_type_mismatch.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use emmylua_parser::{
77
use rowan::{NodeOrToken, TextRange};
88

99
use crate::{
10-
DiagnosticCode, LuaBuiltinAttributeKind, LuaDeclExtra, LuaDeclId, LuaMemberKey,
10+
DbIndex, DiagnosticCode, LuaBuiltinAttributeKind, LuaDeclExtra, LuaDeclId, LuaMemberKey,
1111
LuaSemanticDeclId, LuaType, SemanticDeclLevel, SemanticModel, TypeCheckFailReason,
12-
TypeCheckResult, VariadicType, infer_index_expr,
12+
TypeCheckResult, VariadicType, get_real_type, infer_index_expr,
1313
};
1414

1515
use super::{Checker, DiagnosticContext, humanize_lint_type};
@@ -300,7 +300,8 @@ fn check_table_expr_content(
300300
}
301301
};
302302

303-
if (source_type.is_table() || source_type.is_custom_type())
303+
let real_source_type = get_real_type_or_self(semantic_model.get_db(), &source_type);
304+
if (real_source_type.is_table() || real_source_type.is_custom_type())
304305
&& let Some(table_expr) = LuaTableExpr::cast(value_expr.syntax().clone())
305306
{
306307
// 检查子表
@@ -387,7 +388,8 @@ fn check_assign_type_mismatch(
387388
return Some(false);
388389
}
389390

390-
match (&source_type, &value_type) {
391+
let real_source_type = get_real_type_or_self(semantic_model.get_db(), source_type);
392+
match (real_source_type, value_type) {
391393
// 如果源类型是定义类型, 则仅在目标类型是定义类型或引用类型时进行类型检查
392394
(LuaType::Def(_), LuaType::Def(_) | LuaType::Ref(_)) => {}
393395
(LuaType::Def(_), _) => return Some(false),
@@ -452,3 +454,7 @@ fn add_type_check_diagnostic(
452454
}
453455
}
454456
}
457+
458+
fn get_real_type_or_self<'a>(db: &'a DbIndex, ty: &'a LuaType) -> &'a LuaType {
459+
get_real_type(db, ty).unwrap_or(ty)
460+
}

crates/emmylua_code_analysis/src/diagnostic/test/assign_type_mismatch_test.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,49 @@ return t
10001000
));
10011001
}
10021002

1003+
#[test]
1004+
fn test_optional_alias_field_rejects_table_literal_regardless_of_declaration_order() {
1005+
let mut ws = VirtualWorkspace::new();
1006+
assert!(!ws.has_no_diagnostic(
1007+
DiagnosticCode::AssignTypeMismatch,
1008+
r#"
1009+
---@alias B true?
1010+
1011+
---@class A
1012+
---@field field B
1013+
1014+
---@type A
1015+
local var = { field = {} }
1016+
"#
1017+
));
1018+
1019+
assert!(!ws.has_no_diagnostic(
1020+
DiagnosticCode::AssignTypeMismatch,
1021+
r#"
1022+
---@alias B true?
1023+
1024+
---@class A
1025+
---@field field? B
1026+
1027+
---@type A
1028+
local var = { field = {} }
1029+
"#
1030+
));
1031+
1032+
assert!(!ws.has_no_diagnostic(
1033+
DiagnosticCode::AssignTypeMismatch,
1034+
r#"
1035+
---@class A
1036+
---@field field? B
1037+
1038+
---@alias B true?
1039+
1040+
---@type A
1041+
local var = { field = {} }
1042+
"#
1043+
));
1044+
}
1045+
10031046
#[test]
10041047
fn test_issue_525() {
10051048
let mut ws = VirtualWorkspace::new();

0 commit comments

Comments
 (0)