Fix: undefined-field false positive for table<K,V> when value type is generic and key is not string/integer#1109
Conversation
…eric and key is not string/integer When a table<K,V> field has a generic value type (e.g. Box<unknown>?) and the key type K is not string or integer (e.g. thread, boolean), indexing the table with a correctly-typed key falsely reports undefined-field. Root cause: get_key_types() only recognized string, integer and a few other types, silently dropping thread/boolean/number/userdata. The subsequent ExprType member matching also only handled string and integer. Fix: - Add thread/boolean/number/userdata to get_key_types() - Add fallback equality check in ExprType matching branch - Add test cases for thread and boolean key types
There was a problem hiding this comment.
Code Review: check_field.rs Changes
Issues Found:
-
Potential Logic Error in Key Type Comparison (Line 277)
- The comparison
kt == typusesPartialEqforLuaTypewhich may not handle all type variations correctly (e.g., generic types, type aliases) - Consider using a more robust comparison method like
type_matchor structural equality check
- The comparison
-
Inconsistent Type Handling (Lines 380-383)
- Adding
Boolean,Thread,Number,Userdatatoget_key_typesis correct for basic types - However,
Numbermight overlap withDocIntegerConst- ensure no duplicate handling issues
- Adding
-
Missing Edge Cases (Lines 380-383)
Stringtype is not included in the new block, butDocStringConstis already handled above- Consider if
Niltype should also be included as a potential key type
Recommendations:
- Line 277: Replace direct equality with a type compatibility check:
} else if key_types.iter().any(|kt| typ.is_subtype_of(kt) || kt.is_subtype_of(typ)) {
return Some(());
}- Lines 380-383: Add
Stringtype for consistency:
LuaType::Boolean | LuaType::Thread | LuaType::Number | LuaType::Userdata | LuaType::String => {
type_set.insert(current_type);
}- Test Coverage: Consider adding tests for:
Numberkey type (not justbooleanandthread)Userdatakey type- Mixed key types in table generics
Test File Changes:
- ✅ Tests are well-structured and test the specific scenarios
- ✅ Good use of
VirtualWorkspaceandhas_no_diagnostic - Consider adding negative test cases (where undefined field should be reported)
There was a problem hiding this comment.
Code Review
This pull request expands the field checking diagnostic logic to support additional Lua types (Boolean, Thread, Number, and Userdata) as valid table keys, and includes corresponding unit tests. A review comment suggests optimizing the key type check by using HashSet::contains instead of a linear search, which improves performance.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| } else if key_types.iter().any(|kt| kt == typ) { | ||
| return Some(()); |
There was a problem hiding this comment.
Since key_types is a HashSet<LuaType>, you can use contains for an iter().any(...). This improves performance during diagnostic analysis.
| } else if key_types.iter().any(|kt| kt == typ) { | |
| return Some(()); | |
| } else if key_types.contains(typ) { | |
| return Some(()); |
Related Issue
Fixes #1108
Problem
The bug has two layers in
check_field.rs:Layer 1:
get_key_types()drops non-string/integer built-in typesWhen the key type is
thread,get_key_types()returns an empty set →key_types.is_empty()→ early return → reportsundefined-field.Layer 2:
ExprTypematching only handlesstringandintegerFix
Fix 1: Add built-in types to
get_key_types()Fix 2: Add fallback equality check in
ExprTypematchingFiles Changed
crates/emmylua_code_analysis/src/diagnostic/checker/check_field.rs— fix both layerscrates/emmylua_code_analysis/src/diagnostic/test/undefined_field_test.rs— add 2 test casesTest
Add test cases in
undefined_field_test.rs:Verification
Before fix:
After fix: No warning.