Skip to content

Commit 6467ffe

Browse files
committed
Fix test
Fix #797
1 parent c60f563 commit 6467ffe

File tree

3 files changed

+79
-69
lines changed

3 files changed

+79
-69
lines changed

crates/emmylua_code_analysis/src/semantic/generic/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ result = {
185185
direct: string,
186186
class_a: string,
187187
class_b: string,
188-
class_c: table,
189-
class_d: table,
188+
class_c: string,
189+
class_d: string,
190190
alias_a: string,
191191
alias_b: string,
192192
alias_c: string,

crates/emmylua_code_analysis/src/semantic/generic/tpl_pattern/generic_tpl_pattern.rs

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
use crate::{
2-
InferFailReason, InferGuard, InferGuardRef, LuaGenericType, LuaType, TplContext,
3-
TypeSubstitutor,
4-
semantic::{
5-
generic::tpl_pattern::{
6-
TplPatternMatchResult, tpl_pattern_match, variadic_tpl_pattern_match,
7-
},
8-
type_check::is_sub_type_of,
9-
},
2+
instantiate_type_generic, semantic::generic::tpl_pattern::{
3+
tpl_pattern_match, variadic_tpl_pattern_match, TplPatternMatchResult
4+
}, InferFailReason, InferGuard, InferGuardRef, LuaGenericType, LuaType, TplContext, TypeSubstitutor
105
};
116

127
pub fn generic_tpl_pattern_match(
@@ -27,45 +22,58 @@ fn generic_tpl_pattern_match_inner(
2722
LuaType::Generic(target_generic) => {
2823
let base = source_generic.get_base_type_id_ref();
2924
let target_base = target_generic.get_base_type_id_ref();
30-
31-
if !is_sub_type_of(context.db, target_base, base) {
32-
let target_decl = context
33-
.db
34-
.get_type_index()
35-
.get_type_decl(target_base)
36-
.ok_or(InferFailReason::None)?;
37-
if target_decl.is_alias() {
38-
let substitutor = TypeSubstitutor::from_alias(
39-
target_generic.get_params().clone(),
40-
target_base.clone(),
25+
let target_decl = context
26+
.db
27+
.get_type_index()
28+
.get_type_decl(target_base)
29+
.ok_or(InferFailReason::None)?;
30+
if target_decl.is_alias() {
31+
let substitutor = TypeSubstitutor::from_alias(
32+
target_generic.get_params().clone(),
33+
target_base.clone(),
34+
);
35+
if let Some(origin_type) =
36+
target_decl.get_alias_origin(context.db, Some(&substitutor))
37+
{
38+
return generic_tpl_pattern_match_inner(
39+
context,
40+
source_generic,
41+
&origin_type,
42+
infer_guard,
4143
);
42-
if let Some(origin_type) =
43-
target_decl.get_alias_origin(context.db, Some(&substitutor))
44-
{
45-
return generic_tpl_pattern_match_inner(
46-
context,
47-
source_generic,
48-
&origin_type,
49-
infer_guard,
50-
);
51-
}
5244
}
53-
54-
return Err(InferFailReason::None);
5545
}
5646

57-
let params = source_generic.get_params();
58-
let target_params = target_generic.get_params();
59-
let min_len = params.len().min(target_params.len());
60-
for i in 0..min_len {
61-
match (&params[i], &target_params[i]) {
62-
(LuaType::Variadic(variadict), _) => {
63-
variadic_tpl_pattern_match(context, variadict, &target_params[i..])?;
64-
break;
47+
if base == target_base {
48+
let params = source_generic.get_params();
49+
let target_params = target_generic.get_params();
50+
let min_len = params.len().min(target_params.len());
51+
for i in 0..min_len {
52+
match (&params[i], &target_params[i]) {
53+
(LuaType::Variadic(variadict), _) => {
54+
variadic_tpl_pattern_match(context, variadict, &target_params[i..])?;
55+
break;
56+
}
57+
_ => {
58+
tpl_pattern_match(context, &params[i], &target_params[i])?;
59+
}
6560
}
66-
_ => {
67-
tpl_pattern_match(context, &params[i], &target_params[i])?;
61+
}
62+
} else if let Some(super_types) =
63+
context.db.get_type_index().get_super_types(target_base)
64+
{
65+
for mut super_type in super_types {
66+
if super_type.contain_tpl() {
67+
let substitutor = TypeSubstitutor::from_type_array(target_generic.get_params().clone());
68+
super_type = instantiate_type_generic(context.db, &super_type, &substitutor);
6869
}
70+
71+
generic_tpl_pattern_match_inner(
72+
context,
73+
source_generic,
74+
&super_type,
75+
&infer_guard.fork(),
76+
)?;
6977
}
7078
}
7179
}

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

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ use std::{collections::HashMap, sync::Arc};
22

33
use crate::{
44
LuaGenericType, LuaMemberOwner, LuaType, LuaTypeCache, LuaTypeDeclId, RenderLevel,
5-
TypeSubstitutor, humanize_type,
6-
semantic::{
7-
member::find_members,
8-
type_check::{is_sub_type_of, type_check_context::TypeCheckContext},
9-
},
5+
TypeSubstitutor, humanize_type, instantiate_type_generic,
6+
semantic::{member::find_members, type_check::type_check_context::TypeCheckContext},
107
};
118

129
use super::{
@@ -63,7 +60,14 @@ pub fn check_generic_type_compact(
6360
.get_type_index()
6461
.get_super_types(&compact_generic.get_base_type_id())
6562
{
66-
for super_type in supers {
63+
for mut super_type in supers {
64+
if super_type.contain_tpl() {
65+
let substitutor =
66+
TypeSubstitutor::from_type_array(compact_generic.get_params().clone());
67+
super_type =
68+
instantiate_type_generic(context.db, &super_type, &substitutor);
69+
}
70+
6771
let result = check_generic_type_compact(
6872
context,
6973
source_generic,
@@ -107,28 +111,26 @@ fn check_generic_type_compact_generic(
107111
) -> TypeCheckResult {
108112
let source_base_id = source_generic.get_base_type_id();
109113
let compact_base_id = compact_generic.get_base_type_id();
110-
if !is_sub_type_of(context.db, &compact_base_id, &source_base_id) {
111-
let compact_decl = context
112-
.db
113-
.get_type_index()
114-
.get_type_decl(&compact_base_id)
115-
.ok_or(TypeCheckFailReason::TypeNotMatch)?;
116-
if compact_decl.is_alias() {
117-
let substitutor = TypeSubstitutor::from_alias(
118-
compact_generic.get_params().clone(),
119-
compact_base_id.clone(),
114+
let compact_decl = context
115+
.db
116+
.get_type_index()
117+
.get_type_decl(&compact_base_id)
118+
.ok_or(TypeCheckFailReason::TypeNotMatch)?;
119+
if compact_decl.is_alias() {
120+
let substitutor = TypeSubstitutor::from_alias(
121+
compact_generic.get_params().clone(),
122+
compact_base_id.clone(),
123+
);
124+
if let Some(origin_type) = compact_decl.get_alias_origin(context.db, Some(&substitutor)) {
125+
return check_generic_type_compact(
126+
context,
127+
source_generic,
128+
&origin_type,
129+
check_guard.next_level()?,
120130
);
121-
if let Some(origin_type) = compact_decl.get_alias_origin(context.db, Some(&substitutor))
122-
{
123-
return check_generic_type_compact(
124-
context,
125-
source_generic,
126-
&origin_type,
127-
check_guard.next_level()?,
128-
);
129-
}
130131
}
131-
132+
}
133+
if compact_base_id != source_base_id {
132134
return Err(TypeCheckFailReason::TypeNotMatch);
133135
}
134136

0 commit comments

Comments
 (0)