Skip to content

Commit d2ecc00

Browse files
committed
Fix #369
1 parent 5dc5d66 commit d2ecc00

File tree

5 files changed

+49
-9
lines changed

5 files changed

+49
-9
lines changed

crates/emmylua_code_analysis/src/compilation/test/flow.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,35 @@ end
561561
));
562562
}
563563

564+
#[test]
565+
fn test_issue_369() {
566+
let mut ws = VirtualWorkspace::new();
567+
568+
ws.def(
569+
r#"
570+
--- @enum myenum
571+
local myenum = { A = 1 }
572+
573+
--- @param x myenum|{}
574+
function foo(x)
575+
if type(x) ~= 'table' then
576+
a = x
577+
else
578+
b = x
579+
end
580+
end
581+
"#,
582+
);
583+
584+
let a = ws.expr_ty("a");
585+
let a_expected = ws.ty("myenum");
586+
assert_eq!(a, a_expected);
587+
588+
let b = ws.expr_ty("b");
589+
let b_expected = ws.ty("{}");
590+
assert_eq!(b, b_expected);
591+
}
592+
564593
#[test]
565594
fn test_issue_405() {
566595
let mut ws = VirtualWorkspace::new();

crates/emmylua_code_analysis/src/db_index/type/type_ops/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl TypeOps {
3232
TypeOps::Remove => {
3333
remove_type::remove_type(db, source.clone(), target.clone()).unwrap_or(LuaType::Any)
3434
}
35-
TypeOps::Narrow => narrow_type::narrow_down_type(source.clone(), target.clone())
35+
TypeOps::Narrow => narrow_type::narrow_down_type(db, source.clone(), target.clone())
3636
.unwrap_or(target.clone()),
3737
TypeOps::And => and_type::and_type(source.clone(), target.clone()),
3838
_ => source.clone(),

crates/emmylua_code_analysis/src/db_index/type/type_ops/narrow_type.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use crate::{LuaType, LuaUnionType};
1+
use crate::{DbIndex, LuaType, LuaUnionType};
22

33
// need to be optimized
4-
pub fn narrow_down_type(source: LuaType, target: LuaType) -> Option<LuaType> {
4+
pub fn narrow_down_type(db: &DbIndex, source: LuaType, target: LuaType) -> Option<LuaType> {
55
if source == target {
66
return Some(source);
77
}
@@ -31,16 +31,24 @@ pub fn narrow_down_type(source: LuaType, target: LuaType) -> Option<LuaType> {
3131
LuaType::TableConst(_) => {
3232
return Some(source);
3333
}
34+
LuaType::Object(_) => {
35+
return Some(source);
36+
}
3437
LuaType::Table | LuaType::Userdata | LuaType::Any | LuaType::Unknown => {
3538
return Some(LuaType::Table);
3639
}
37-
LuaType::Ref(_)
38-
| LuaType::Def(_)
39-
| LuaType::Global
40+
LuaType::Global
4041
| LuaType::Array(_)
4142
| LuaType::Tuple(_)
4243
| LuaType::Generic(_)
4344
| LuaType::TableGeneric(_) => return Some(source),
45+
LuaType::Ref(type_decl_id) | LuaType::Def(type_decl_id) => {
46+
let type_decl = db.get_type_index().get_type_decl(type_decl_id)?;
47+
// enum 在实际使用时实际上是 enum.field, 并不等于 table
48+
if !type_decl.is_enum() {
49+
return Some(source);
50+
}
51+
}
4452
_ => {}
4553
},
4654
LuaType::Function => {
@@ -117,7 +125,7 @@ pub fn narrow_down_type(source: LuaType, target: LuaType) -> Option<LuaType> {
117125
| LuaType::TableGeneric(_) => return Some(source),
118126
_ => {}
119127
},
120-
LuaType::Instance(base) => return narrow_down_type(source, base.get_base().clone()),
128+
LuaType::Instance(base) => return narrow_down_type(db, source, base.get_base().clone()),
121129
LuaType::Unknown => return Some(source),
122130
_ => {
123131
if target.is_unknown() {
@@ -133,7 +141,7 @@ pub fn narrow_down_type(source: LuaType, target: LuaType) -> Option<LuaType> {
133141
let mut union_types = union
134142
.get_types()
135143
.iter()
136-
.filter_map(|t| narrow_down_type(t.clone(), target.clone()))
144+
.filter_map(|t| narrow_down_type(db, t.clone(), target.clone()))
137145
.collect::<Vec<_>>();
138146

139147
union_types.dedup();

crates/emmylua_code_analysis/src/db_index/type/type_ops/remove_type.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ pub fn remove_type(db: &DbIndex, source: LuaType, removed_type: LuaType) -> Opti
6767
| LuaType::TableGeneric(_) => return None,
6868
LuaType::Ref(type_decl_id) | LuaType::Def(type_decl_id) => {
6969
let type_decl = db.get_type_index().get_type_decl(type_decl_id)?;
70+
// enum 在实际使用时实际上是 enum.field, 并不等于 table
71+
if type_decl.is_enum() {
72+
return Some(source);
73+
}
7074
if type_decl.is_alias() {
7175
if let Some(alias_ref) = get_real_type(db, &source) {
7276
return remove_type(db, alias_ref.clone(), removed_type);

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,6 @@ return t
822822
"#
823823
));
824824
}
825-
826825
#[test]
827826
fn test_issue_393() {
828827
let mut ws = VirtualWorkspace::new();

0 commit comments

Comments
 (0)