Skip to content

Commit 211fc24

Browse files
committed
Fix #330
1 parent 0bd5c30 commit 211fc24

File tree

2 files changed

+53
-51
lines changed

2 files changed

+53
-51
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,4 +805,21 @@ return t
805805
"#
806806
));
807807
}
808+
809+
#[test]
810+
fn test_issue_330() {
811+
let mut ws = VirtualWorkspace::new();
812+
assert!(ws.check_code_for(
813+
DiagnosticCode::AssignTypeMismatch,
814+
r#"
815+
---@enum MyEnum
816+
local MyEnum = { A = 1, B = 2 }
817+
818+
local x --- @type MyEnum?
819+
820+
---@type MyEnum
821+
local a = x or MyEnum.A
822+
"#
823+
));
824+
}
808825
}

crates/emmylua_code_analysis/src/semantic/type_check/ref_type.rs

Lines changed: 36 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashMap;
1+
use std::{collections::HashMap, sync::Arc};
22

33
use crate::{
44
humanize_type, semantic::member::infer_members, DbIndex, LuaMemberKey, LuaMemberOwner,
@@ -39,72 +39,57 @@ pub fn check_ref_type_compact(
3939

4040
if type_decl.is_enum() {
4141
match compact_type {
42-
LuaType::Def(compact_id) => {
43-
if source_id == compact_id {
44-
return Ok(());
45-
}
46-
}
47-
LuaType::Ref(compact_id) => {
42+
LuaType::Def(compact_id) | LuaType::Ref(compact_id) => {
4843
if source_id == compact_id {
4944
return Ok(());
5045
}
5146
}
5247
_ => {}
5348
};
54-
55-
let enum_member_owner = LuaMemberOwner::Type(source_id.clone());
56-
let enum_members = db
57-
.get_member_index()
58-
.get_members(&enum_member_owner)
59-
.ok_or(TypeCheckFailReason::TypeNotMatch)?;
60-
61-
let mut union_types = Vec::new();
62-
if type_decl.is_enum_key() {
63-
for enum_member in enum_members {
64-
let member_key = enum_member.get_key();
65-
let fake_type = match member_key {
66-
LuaMemberKey::Name(name) => LuaType::DocStringConst(name.clone().into()),
67-
LuaMemberKey::Integer(i) => LuaType::IntegerConst(i.clone()),
68-
LuaMemberKey::None => continue,
69-
LuaMemberKey::Expr(_) => continue,
70-
};
71-
72-
union_types.push(fake_type);
73-
}
74-
} else {
75-
for member in enum_members {
76-
if let Some(type_cache) =
77-
db.get_type_index().get_type_cache(&member.get_id().into())
78-
{
79-
let member_fake_type = match type_cache.as_type() {
80-
LuaType::StringConst(s) => &LuaType::DocStringConst(s.clone().into()),
81-
LuaType::IntegerConst(i) => &LuaType::DocIntegerConst(i.clone()),
82-
_ => &type_cache.as_type(),
83-
};
84-
85-
union_types.push(member_fake_type.clone());
49+
// 移除掉枚举类型本身
50+
let mut compact_type = compact_type.clone();
51+
match compact_type {
52+
LuaType::Union(union_types) => {
53+
let mut new_union_types = Vec::new();
54+
let union_types = union_types.get_types();
55+
for typ in union_types {
56+
if let LuaType::Def(compact_id) | LuaType::Ref(compact_id) = typ {
57+
if compact_id != source_id {
58+
new_union_types.push(typ.clone());
59+
}
60+
continue;
61+
}
62+
new_union_types.push(typ.clone());
8663
}
64+
compact_type = LuaType::Union(Arc::new(LuaUnionType::new(new_union_types)));
8765
}
66+
_ => {}
8867
}
8968

90-
// 当 enum 的值全为整数常量时, 可能会用于位运算, 此时右值推断为整数
91-
if union_types
92-
.iter()
93-
.all(|t| matches!(t, LuaType::DocIntegerConst(_)))
94-
{
95-
match compact_type {
96-
LuaType::Integer => {
97-
return Ok(());
69+
let Some(enum_fields) = type_decl.get_enum_field_type(db) else {
70+
return Err(TypeCheckFailReason::TypeNotMatch);
71+
};
72+
73+
if let LuaType::Union(union_types) = &enum_fields {
74+
// 当 enum 的值全为整数常量时, 可能会用于位运算, 此时右值推断为整数
75+
if union_types
76+
.get_types()
77+
.iter()
78+
.all(|t| matches!(t, LuaType::DocIntegerConst(_)))
79+
{
80+
match compact_type {
81+
LuaType::Integer => {
82+
return Ok(());
83+
}
84+
_ => {}
9885
}
99-
_ => {}
10086
}
10187
}
10288

103-
let fake_union_type = LuaType::Union(LuaUnionType::new(union_types).into());
10489
return check_general_type_compact(
10590
db,
106-
&fake_union_type,
107-
compact_type,
91+
&enum_fields,
92+
&compact_type,
10893
check_guard.next_level()?,
10994
);
11095
} else {

0 commit comments

Comments
 (0)