Skip to content

Commit 18e4e8c

Browse files
committed
fix(semantic): avoid broad lookup for exact missing keys
Exact name and integer keys already have a direct member lookup. When that misses, returning FieldNotFound avoids scanning every broad compatible member and unioning unrelated signatures. Assisted-by: Codex
1 parent 3c6d2ca commit 18e4e8c

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,24 @@ mod test {
3636
assert_eq!(c_ty, union_type);
3737
}
3838

39+
#[test]
40+
fn test_exact_missing_table_key_does_not_scan_broad_members() {
41+
let mut ws = VirtualWorkspace::new_with_init_std_lib();
42+
43+
ws.def(
44+
r#"
45+
local t = {
46+
a = 1,
47+
b = "b",
48+
}
49+
50+
value = t["missing"]
51+
"#,
52+
);
53+
54+
assert_eq!(ws.expr_ty("value"), LuaType::Nil);
55+
}
56+
3957
#[test]
4058
fn test_issue_314_generic_inheritance() {
4159
let mut ws = VirtualWorkspace::new_with_init_std_lib();

crates/emmylua_code_analysis/src/semantic/infer/infer_index/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,11 @@ fn infer_table_member(
348348
return member_item.resolve_type(db);
349349
}
350350

351+
if matches!(key, LuaMemberKey::Name(_) | LuaMemberKey::Integer(_)) {
352+
// Exact keys already missed above. The matching scan is only for broad keys.
353+
return Err(InferFailReason::FieldNotFound);
354+
}
355+
351356
if let Some(result_type) = infer_type_key_member_type(db, key_type, &owner) {
352357
return Ok(result_type);
353358
}
@@ -386,7 +391,10 @@ fn infer_custom_type_member(
386391
return member_item.resolve_type(db);
387392
}
388393

389-
if let Some(result_type) = infer_type_key_member_type(db, &lookup.key_type, &owner) {
394+
// Exact keys may still resolve through super types below; only broad keys need key-type matching here.
395+
if !matches!(lookup.key, LuaMemberKey::Name(_) | LuaMemberKey::Integer(_))
396+
&& let Some(result_type) = infer_type_key_member_type(db, &lookup.key_type, &owner)
397+
{
390398
return Ok(result_type);
391399
}
392400

0 commit comments

Comments
 (0)