Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ pub(super) fn is_valid_member(
}
} else if typ.is_integer() && key_types.iter().any(|typ| typ.is_integer()) {
return Some(());
} else if key_types.iter().any(|kt| kt == typ) {
return Some(());
Comment on lines +277 to +278

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since key_types is a HashSet<LuaType>, you can use contains for an $O(1)$ lookup instead of performing a linear $O(N)$ scan with iter().any(...). This improves performance during diagnostic analysis.

Suggested change
} else if key_types.iter().any(|kt| kt == typ) {
return Some(());
} else if key_types.contains(typ) {
return Some(());

}
}
LuaMemberKey::Name(_) => {
Expand Down Expand Up @@ -378,6 +380,9 @@ fn get_key_types(db: &DbIndex, typ: &LuaType) -> HashSet<LuaType> {
LuaType::DocStringConst(_) | LuaType::DocIntegerConst(_) => {
type_set.insert(current_type);
}
LuaType::Boolean | LuaType::Thread | LuaType::Number | LuaType::Userdata => {
type_set.insert(current_type);
}
LuaType::Call(alias_call) => {
if let Some(key_types) = get_keyof_keys(db, alias_call) {
for t in key_types {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -900,4 +900,48 @@ mod test {
assert_eq!(ws.expr_ty("alias_result"), ws.ty("string?"));
assert_eq!(ws.expr_ty("numeric_result"), ws.ty("string?"));
}

#[test]
fn test_table_generic_value_with_thread_key() {
let mut ws = VirtualWorkspace::new();
assert!(ws.has_no_diagnostic(
DiagnosticCode::UndefinedField,
r#"
---@class Box<T>
---@field value T

---@class Container
---@field items table<thread, Box<unknown>?>
local Container = {}

---@param co thread
function Container:get(co)
local item = self.items[co]
return item
end
"#
));
}

#[test]
fn test_table_generic_value_with_boolean_key() {
let mut ws = VirtualWorkspace::new();
assert!(ws.has_no_diagnostic(
DiagnosticCode::UndefinedField,
r#"
---@class Box<T>
---@field value T

---@class Container
---@field items table<boolean, Box<unknown>?>
local Container = {}

---@param key boolean
function Container:get(key)
local item = self.items[key]
return item
end
"#
));
}
}
Loading