Skip to content

Commit 930b63e

Browse files
committed
fix typecheck: def/ref match Generic
1 parent 06651c4 commit 930b63e

File tree

4 files changed

+67
-74
lines changed

4 files changed

+67
-74
lines changed

crates/emmylua_code_analysis/src/db_index/type/humanize_type.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ fn humanize_generic_type(db: &DbIndex, generic: &LuaGenericType, level: RenderLe
476476
None => return base_id.get_name().to_string(),
477477
};
478478

479-
let simple_name = type_decl.get_name();
479+
let full_name = type_decl.get_full_name();
480480
match level {
481481
RenderLevel::Brief => {
482482
if type_decl.is_alias() {
@@ -501,7 +501,7 @@ fn humanize_generic_type(db: &DbIndex, generic: &LuaGenericType, level: RenderLe
501501
.collect::<Vec<_>>()
502502
.join(",");
503503

504-
format!("{}<{}>", simple_name, generic_params)
504+
format!("{}<{}>", full_name, generic_params)
505505
}
506506

507507
fn humanize_table_const_type_detail_and_simple(

crates/emmylua_code_analysis/src/diagnostic/checker/return_type_mismatch.rs

Lines changed: 26 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use emmylua_parser::{
44
use rowan::{NodeOrToken, TextRange};
55

66
use crate::{
7-
diagnostic::checker::assign_type_mismatch::check_table_expr, humanize_type, DiagnosticCode,
8-
LuaSemanticDeclId, LuaSignatureId, LuaType, RenderLevel, SemanticDeclLevel, SemanticModel,
7+
diagnostic::checker::{assign_type_mismatch::check_table_expr, humanize_lint_type},
8+
DiagnosticCode, LuaSemanticDeclId, LuaSignatureId, LuaType, SemanticDeclLevel, SemanticModel,
99
SignatureReturnStatus, TypeCheckFailReason, TypeCheckResult,
1010
};
1111

@@ -127,6 +127,8 @@ fn check_return_stat(
127127
let return_expr_type = &return_expr_types[0];
128128
let return_expr_range = return_expr_ranges[0];
129129
let result = semantic_model.type_check(check_type, &return_expr_type);
130+
dbg!(&check_type);
131+
dbg!(&return_expr_type);
130132
if !result.is_ok() {
131133
if return_expr_type.is_table() {
132134
if let Some(return_expr) = return_exprs.get(0) {
@@ -160,34 +162,6 @@ fn check_return_stat(
160162
Some(())
161163
}
162164

163-
// fn check_variadic_return_type_match(
164-
// context: &mut DiagnosticContext,
165-
// semantic_model: &SemanticModel,
166-
// start_idx: usize,
167-
// variadic_type: &LuaType,
168-
// return_expr_types: &[LuaType],
169-
// return_expr_ranges: &[TextRange],
170-
// ) {
171-
// let mut idx = start_idx;
172-
// for (return_expr_type, return_expr_range) in
173-
// return_expr_types.iter().zip(return_expr_ranges.iter())
174-
// {
175-
// let result = semantic_model.type_check(variadic_type, return_expr_type);
176-
// if !result.is_ok() {
177-
// add_type_check_diagnostic(
178-
// context,
179-
// semantic_model,
180-
// start_idx + idx,
181-
// *return_expr_range,
182-
// variadic_type,
183-
// return_expr_type,
184-
// result,
185-
// );
186-
// }
187-
// idx += 1;
188-
// }
189-
// }
190-
191165
fn add_type_check_diagnostic(
192166
context: &mut DiagnosticContext,
193167
semantic_model: &SemanticModel,
@@ -200,47 +174,28 @@ fn add_type_check_diagnostic(
200174
let db = semantic_model.get_db();
201175
match result {
202176
Ok(_) => return,
203-
Err(reason) => match reason {
204-
TypeCheckFailReason::TypeNotMatchWithReason(reason) => {
205-
context.add_diagnostic(
206-
DiagnosticCode::ReturnTypeMismatch,
207-
range,
208-
t!(
209-
"Annotations specify that return value %{index} has a type of `%{source}`, returning value of type `%{found}` here instead. %{reason}",
210-
index = index + 1,
211-
source = humanize_type(db, &param_type, RenderLevel::Simple),
212-
found = humanize_type(db, &expr_type, RenderLevel::Simple),
213-
reason = reason
214-
)
215-
.to_string(),
216-
None,
217-
);
218-
}
219-
TypeCheckFailReason::TypeNotMatch => {
220-
context.add_diagnostic(
221-
DiagnosticCode::ReturnTypeMismatch,
222-
range,
223-
t!(
224-
"Annotations specify that return value %{index} has a type of `%{source}`, returning value of type `%{found}` here instead. %{reason}",
225-
index = index + 1,
226-
source = humanize_type(db, &param_type, RenderLevel::Simple),
227-
found = humanize_type(db, &expr_type, RenderLevel::Simple),
228-
reason = ""
229-
)
230-
.to_string(),
231-
None,
232-
);
233-
}
234-
TypeCheckFailReason::TypeRecursion => {
235-
context.add_diagnostic(
236-
DiagnosticCode::ReturnTypeMismatch,
237-
range,
238-
"type recursion".into(),
239-
None,
240-
);
241-
}
242-
TypeCheckFailReason::DonotCheck => {}
243-
},
177+
Err(reason) => {
178+
let reason_message = match reason {
179+
TypeCheckFailReason::TypeNotMatchWithReason(reason) => reason,
180+
TypeCheckFailReason::TypeNotMatch | TypeCheckFailReason::DonotCheck => {
181+
"".to_string()
182+
}
183+
TypeCheckFailReason::TypeRecursion => "type recursion".to_string(),
184+
};
185+
context.add_diagnostic(
186+
DiagnosticCode::ReturnTypeMismatch,
187+
range,
188+
t!(
189+
"Annotations specify that return value %{index} has a type of `%{source}`, returning value of type `%{found}` here instead. %{reason}",
190+
index = index + 1,
191+
source = humanize_lint_type(db, &param_type),
192+
found = humanize_lint_type(db, &expr_type),
193+
reason = reason_message
194+
)
195+
.to_string(),
196+
None,
197+
);
198+
}
244199
}
245200
}
246201

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,4 +423,27 @@ mod tests {
423423
"#
424424
));
425425
}
426+
427+
#[test]
428+
fn test_super_alias() {
429+
let mut ws = VirtualWorkspace::new_with_init_std_lib();
430+
assert!(ws.check_code_for(
431+
DiagnosticCode::ReturnTypeMismatch,
432+
r#"
433+
---@namespace Test
434+
435+
---@alias A fun()
436+
437+
---@class B<T>: A
438+
439+
---@return A
440+
local function subscribe()
441+
---@type B<string>
442+
local a
443+
444+
return a
445+
end
446+
"#
447+
));
448+
}
426449
}

crates/emmylua_code_analysis/src/semantic/type_check/ref_type.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,16 @@ pub fn check_ref_type_compact(
2727

2828
if type_decl.is_alias() {
2929
if let Some(origin_type) = type_decl.get_alias_origin(db, None) {
30-
return check_general_type_compact(
30+
let result = check_general_type_compact(
3131
db,
3232
&origin_type,
3333
compact_type,
3434
check_guard.next_level()?,
3535
);
36+
if result.is_err() && origin_type.is_function() {
37+
return check_ref_class(db, source_id, compact_type, check_guard);
38+
}
39+
return result;
3640
}
3741

3842
return Err(TypeCheckFailReason::TypeNotMatch);
@@ -176,6 +180,17 @@ fn check_ref_class(
176180
LuaType::Tuple(tuple_type) => {
177181
check_ref_type_compact_tuple(db, tuple_type, source_id, check_guard.next_level()?)
178182
}
183+
LuaType::Generic(generic) => {
184+
let base_type_id = generic.get_base_type_id();
185+
if source_id == &base_type_id
186+
|| is_sub_type_of(db, &base_type_id, source_id)
187+
|| is_sub_type_of(db, source_id, &base_type_id)
188+
{
189+
Ok(())
190+
} else {
191+
Err(TypeCheckFailReason::TypeNotMatch)
192+
}
193+
}
179194
_ => {
180195
if let Some(base_type_id) = get_base_type_id(compact_type) {
181196
if source_id == &base_type_id

0 commit comments

Comments
 (0)