1
1
use super :: { find_error:: FindTypeError , ResolveTypeCtx } ;
2
2
use crate :: {
3
- asg:: { self } ,
4
- ast:: TypeArg ,
3
+ asg:: { self , TypeParam , TypeParamError } ,
4
+ ast:: { self , TypeArg } ,
5
5
name:: Name ,
6
- resolve:: error:: ResolveErrorKind ,
6
+ resolve:: error:: ResolveError ,
7
+ source_files:: Source ,
7
8
} ;
8
- use itertools:: Itertools ;
9
9
use std:: borrow:: Cow ;
10
10
11
11
impl < ' a > ResolveTypeCtx < ' a > {
12
12
pub fn find (
13
13
& self ,
14
14
name : & Name ,
15
- arguments : & [ TypeArg ] ,
15
+ type_args : & [ TypeArg ] ,
16
+ source : Source ,
16
17
) -> Result < Cow < ' a , asg:: TypeKind > , FindTypeError > {
17
18
let settings = & self . asg . workspace . settings [ self
18
19
. asg
@@ -24,88 +25,107 @@ impl<'a> ResolveTypeCtx<'a> {
24
25
. expect ( "valid settings id" )
25
26
. 0 ] ;
26
27
27
- if let Some ( decl) = name
28
+ let decl = name
28
29
. as_plain_str ( )
29
30
. and_then ( |name| {
30
31
self . types_in_modules
31
32
. get ( & self . module_fs_node_id )
32
33
. and_then ( |types_in_module| types_in_module. get ( name) )
33
34
} )
34
- // NOTE: This will need to be map instead at some point
35
- . filter ( |decl| decl. num_parameters ( self . asg ) == arguments. len ( ) )
36
- {
37
- if let asg:: TypeKind :: Structure ( human_name, struct_ref, _) = & decl. kind {
38
- let arguments = arguments
39
- . iter ( )
40
- . flat_map ( |arg| match arg {
41
- TypeArg :: Type ( ty) => self . resolve ( ty) ,
42
- TypeArg :: Expr ( expr) => Err ( ResolveErrorKind :: Other {
43
- message :
44
- "Expressions cannot be used as type parameters to structures yet"
45
- . into ( ) ,
46
- }
47
- . at ( expr. source ) ) ,
48
- } )
49
- . collect_vec ( ) ;
35
+ . filter ( |local| local. num_parameters ( self . asg ) == type_args. len ( ) )
36
+ . map ( Ok )
37
+ . unwrap_or_else ( || {
38
+ if name. namespace . is_empty ( ) {
39
+ return Err ( FindTypeError :: NotDefined ) ;
40
+ }
50
41
51
- return Ok ( Cow :: Owned ( asg:: TypeKind :: Structure (
52
- human_name. clone ( ) ,
53
- * struct_ref,
54
- arguments,
55
- ) ) ) ;
56
- }
42
+ let Name {
43
+ namespace,
44
+ basename,
45
+ ..
46
+ } = name;
57
47
58
- if let asg:: TypeKind :: Trait ( human_name, trait_ref, _) = & decl. kind {
59
- let arguments = arguments
60
- . iter ( )
61
- . flat_map ( |arg| match arg {
62
- TypeArg :: Type ( ty) => self . resolve ( ty) ,
63
- TypeArg :: Expr ( expr) => Err ( ResolveErrorKind :: Other {
64
- message : "Expressions cannot be used as type parameters to traits yet"
65
- . into ( ) ,
66
- }
67
- . at ( expr. source ) ) ,
68
- } )
69
- . collect_vec ( ) ;
48
+ let mut matches = settings
49
+ . namespace_to_dependency
50
+ . get ( namespace. as_ref ( ) )
51
+ . into_iter ( )
52
+ . flatten ( )
53
+ . flat_map ( |dep| settings. dependency_to_module . get ( dep) )
54
+ . flat_map ( |fs_node_id| self . types_in_modules . get ( fs_node_id) )
55
+ . flat_map ( |decls| decls. get ( basename. as_ref ( ) ) )
56
+ . filter ( |decl| decl. privacy . is_public ( ) )
57
+ . filter ( |decl| decl. num_parameters ( self . asg ) == type_args. len ( ) ) ;
70
58
71
- return Ok ( Cow :: Owned ( asg:: TypeKind :: Trait (
72
- human_name. clone ( ) ,
73
- * trait_ref,
74
- arguments,
75
- ) ) ) ;
76
- }
59
+ if let Some ( found) = matches. next ( ) {
60
+ if matches. next ( ) . is_some ( ) {
61
+ Err ( FindTypeError :: Ambiguous )
62
+ } else {
63
+ Ok ( found)
64
+ }
65
+ } else {
66
+ Err ( FindTypeError :: NotDefined )
67
+ }
68
+ } ) ?;
77
69
78
- return Ok ( Cow :: Borrowed ( & decl. kind ) ) ;
79
- }
70
+ let mut type_args = type_args. into_iter ( ) . enumerate ( ) ;
80
71
81
- if !name . namespace . is_empty ( ) {
82
- let Name {
83
- namespace ,
84
- basename ,
85
- ..
86
- } = name ;
72
+ let filled = decl
73
+ . kind
74
+ . map_type_params ( |_hint| {
75
+ let Some ( ( _i , value ) ) = type_args . next ( ) else {
76
+ return Err ( FindTypeError :: TypeArgsLengthMismatch ) ;
77
+ } ;
87
78
88
- let mut matches = settings
89
- . namespace_to_dependency
90
- . get ( namespace. as_ref ( ) )
91
- . into_iter ( )
92
- . flatten ( )
93
- . flat_map ( |dep| settings. dependency_to_module . get ( dep) )
94
- . flat_map ( |fs_node_id| self . types_in_modules . get ( fs_node_id) )
95
- . flat_map ( |decls| decls. get ( basename. as_ref ( ) ) )
96
- . filter ( |decl| decl. privacy . is_public ( ) )
97
- // NOTE: This will need to be flat_map instead at some point
98
- . filter ( |decl| decl. num_parameters ( self . asg ) == arguments. len ( ) ) ;
79
+ match value {
80
+ TypeArg :: Type ( ty) => self
81
+ . resolve ( ty)
82
+ . map ( Cow :: Owned )
83
+ . map ( TypeParam :: Type )
84
+ . map_err ( FindTypeError :: ResolveError ) ,
85
+ TypeArg :: Expr ( expr) => {
86
+ let ast:: ExprKind :: Integer ( ast:: Integer :: Generic ( value) ) = & expr. kind
87
+ else {
88
+ return Err ( FindTypeError :: ResolveError ( ResolveError :: other (
89
+ "Expressions are not supported as type arguments yet" ,
90
+ source,
91
+ ) ) ) ;
92
+ } ;
99
93
100
- if let Some ( found) = matches. next ( ) {
101
- if matches. next ( ) . is_some ( ) {
102
- return Err ( FindTypeError :: Ambiguous ) ;
103
- } else {
104
- return Ok ( Cow :: Borrowed ( & found. kind ) ) ;
94
+ u64:: try_from ( value) . map ( TypeParam :: Size ) . map_err ( |_| {
95
+ FindTypeError :: ResolveError ( ResolveError :: other (
96
+ "Size is too large" ,
97
+ source,
98
+ ) )
99
+ } )
100
+ }
105
101
}
106
- }
107
- }
102
+ } )
103
+ . map_err ( |err| match err {
104
+ TypeParamError :: MappingError ( e) => e,
105
+ TypeParamError :: ExpectedType { index } => {
106
+ FindTypeError :: ResolveError ( ResolveError :: other (
107
+ format ! ( "Expected type for type argument {}" , index + 1 ) ,
108
+ source,
109
+ ) )
110
+ }
111
+ TypeParamError :: ExpectedSize { index } => {
112
+ FindTypeError :: ResolveError ( ResolveError :: other (
113
+ format ! ( "Expected size for type argument {}" , index + 1 ) ,
114
+ source,
115
+ ) )
116
+ }
117
+ TypeParamError :: ExpectedSizeValue { index, value } => {
118
+ FindTypeError :: ResolveError ( ResolveError :: other (
119
+ format ! ( "Expected size of {} of type argument {}" , value, index + 1 ) ,
120
+ source,
121
+ ) )
122
+ }
123
+ } ) ;
124
+
125
+ if type_args. next ( ) . is_some ( ) {
126
+ return Err ( FindTypeError :: TypeArgsLengthMismatch ) ;
127
+ } ;
108
128
109
- Err ( FindTypeError :: NotDefined )
129
+ filled
110
130
}
111
131
}
0 commit comments