11use 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
127pub 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 }
0 commit comments