Skip to content

Commit a3806a7

Browse files
committed
fix(checker): GenericConstraintMismatch
1 parent 95ba21b commit a3806a7

2 files changed

Lines changed: 49 additions & 3 deletions

File tree

crates/emmylua_code_analysis/src/diagnostic/checker/generic/generic_constraint_mismatch.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,10 @@ fn check_doc_tag_type(
590590
.get_db()
591591
.get_type_index()
592592
.get_generic_params(&generic_type.get_base_type_id())?;
593+
let substitutor = TypeSubstitutor::from_alias(
594+
generic_type.get_params().clone(),
595+
generic_type.get_base_type_id(),
596+
);
593597
for (i, param_type) in generic_type
594598
.get_params()
595599
.iter()
@@ -602,14 +606,19 @@ fn check_doc_tag_type(
602606
else {
603607
continue;
604608
};
605-
let result = semantic_model.type_check_detail(extend_type, param_type);
609+
let extend_type = normalize_constraint_type(
610+
semantic_model.get_db(),
611+
instantiate_type_generic(semantic_model.get_db(), extend_type, &substitutor),
612+
);
613+
let param_type = normalize_constraint_type(semantic_model.get_db(), param_type.clone());
614+
let result = semantic_model.type_check_detail(&extend_type, &param_type);
606615
if result.is_err() {
607616
add_type_check_diagnostic(
608617
context,
609618
semantic_model,
610619
explicit_args.get(i)?.get_range(),
611-
extend_type,
612-
param_type,
620+
&extend_type,
621+
&param_type,
613622
result,
614623
);
615624
}

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,43 @@ mod test {
226226
));
227227
}
228228

229+
#[test]
230+
fn test_alias_keyof_constraint_accepts_union_of_valid_keys() {
231+
let mut ws = VirtualWorkspace::new();
232+
assert!(ws.has_no_diagnostic(
233+
DiagnosticCode::GenericConstraintMismatch,
234+
r#"
235+
---@class A
236+
---@field one 1
237+
---@field two 2
238+
---@field three 3
239+
240+
---@alias Pick<T, K extends keyof T> nil
241+
242+
---@type Pick<A, 'one' | 'two'>
243+
local tmp
244+
"#,
245+
));
246+
}
247+
248+
#[test]
249+
fn test_alias_keyof_constraint_rejects_union_with_invalid_key() {
250+
let mut ws = VirtualWorkspace::new();
251+
assert!(!ws.has_no_diagnostic(
252+
DiagnosticCode::GenericConstraintMismatch,
253+
r#"
254+
---@class A
255+
---@field one 1
256+
---@field two 2
257+
258+
---@alias Pick<T, K extends keyof T> nil
259+
260+
---@type Pick<A, 'one' | 'missing'>
261+
local tmp
262+
"#,
263+
));
264+
}
265+
229266
#[test]
230267
fn test_class_generic_default_constraint_match() {
231268
let mut ws = VirtualWorkspace::new();

0 commit comments

Comments
 (0)