@@ -16,12 +16,18 @@ pub struct Types {
16
16
#[ derive( Default , Clone , Copy , Debug ) ]
17
17
pub struct TypeInfo {
18
18
/// Whether or not this type is ever used (transitively) within the
19
- /// parameter of a function.
20
- pub param : bool ,
19
+ /// parameter of an imported function.
20
+ ///
21
+ /// This means that it's used in a context where ownership isn't
22
+ /// relinquished.
23
+ pub borrowed : bool ,
21
24
22
25
/// Whether or not this type is ever used (transitively) within the
23
- /// result of a function.
24
- pub result : bool ,
26
+ /// parameter or result of an export, or the result of an import.
27
+ ///
28
+ /// This means that it's used in a context where ownership is required and
29
+ /// memory management is necessary.
30
+ pub owned : bool ,
25
31
26
32
/// Whether or not this type is ever used (transitively) within the
27
33
/// error case in the result of a function.
@@ -33,8 +39,8 @@ pub struct TypeInfo {
33
39
34
40
impl std:: ops:: BitOrAssign for TypeInfo {
35
41
fn bitor_assign ( & mut self , rhs : Self ) {
36
- self . param |= rhs. param ;
37
- self . result |= rhs. result ;
42
+ self . borrowed |= rhs. borrowed ;
43
+ self . owned |= rhs. owned ;
38
44
self . error |= rhs. error ;
39
45
self . has_list |= rhs. has_list ;
40
46
}
@@ -45,29 +51,63 @@ impl Types {
45
51
for ( t, _) in resolve. types . iter ( ) {
46
52
self . type_id_info ( resolve, t) ;
47
53
}
48
- for ( _, iface) in resolve. interfaces . iter ( ) {
49
- for ( _, f) in iface. functions . iter ( ) {
50
- self . type_info_func ( resolve, f) ;
51
- }
52
- }
53
54
for ( _, world) in resolve. worlds . iter ( ) {
54
- for ( _, item) in world. imports . iter ( ) . chain ( & world. exports ) {
55
+ for ( import, ( _, item) ) in world
56
+ . imports
57
+ . iter ( )
58
+ . map ( |i| ( true , i) )
59
+ . chain ( world. exports . iter ( ) . map ( |i| ( false , i) ) )
60
+ {
55
61
match item {
56
62
WorldItem :: Function ( f) => {
57
- self . type_info_func ( resolve, f) ;
63
+ self . type_info_func ( resolve, f, import ) ;
58
64
}
59
- WorldItem :: Interface ( _) | WorldItem :: Type ( _) => { }
65
+ WorldItem :: Interface ( id) => {
66
+ for ( _, f) in resolve. interfaces [ * id] . functions . iter ( ) {
67
+ self . type_info_func ( resolve, f, import) ;
68
+ }
69
+ }
70
+ WorldItem :: Type ( _) => { }
60
71
}
61
72
}
62
73
}
63
74
}
64
75
65
- fn type_info_func ( & mut self , resolve : & Resolve , f : & Function ) {
66
- for ( _, ty) in f. params . iter ( ) {
67
- self . set_param_result_ty ( resolve, ty, true , false , false ) ;
76
+ fn type_info_func ( & mut self , resolve : & Resolve , func : & Function , import : bool ) {
77
+ let mut live = LiveTypes :: default ( ) ;
78
+ for ( _, ty) in func. params . iter ( ) {
79
+ self . type_info ( resolve, ty) ;
80
+ live. add_type ( resolve, ty) ;
81
+ }
82
+ for id in live. iter ( ) {
83
+ let info = self . type_info . get_mut ( & id) . unwrap ( ) ;
84
+ if import {
85
+ info. borrowed = true ;
86
+ } else {
87
+ info. owned = true ;
88
+ }
68
89
}
69
- for ty in f. results . iter_types ( ) {
70
- self . set_param_result_ty ( resolve, ty, false , true , false ) ;
90
+ let mut live = LiveTypes :: default ( ) ;
91
+ for ty in func. results . iter_types ( ) {
92
+ self . type_info ( resolve, ty) ;
93
+ live. add_type ( resolve, ty) ;
94
+ }
95
+ for id in live. iter ( ) {
96
+ self . type_info . get_mut ( & id) . unwrap ( ) . owned = true ;
97
+ }
98
+
99
+ for ty in func. results . iter_types ( ) {
100
+ let id = match ty {
101
+ Type :: Id ( id) => * id,
102
+ _ => continue ,
103
+ } ;
104
+ let err = match & resolve. types [ id] . kind {
105
+ TypeDefKind :: Result ( Result_ { err, .. } ) => err,
106
+ _ => continue ,
107
+ } ;
108
+ if let Some ( Type :: Id ( id) ) = err {
109
+ self . type_info . get_mut ( & id) . unwrap ( ) . error = true ;
110
+ }
71
111
}
72
112
}
73
113
@@ -146,110 +186,6 @@ impl Types {
146
186
None => TypeInfo :: default ( ) ,
147
187
}
148
188
}
149
-
150
- fn set_param_result_id (
151
- & mut self ,
152
- resolve : & Resolve ,
153
- ty : TypeId ,
154
- param : bool ,
155
- result : bool ,
156
- error : bool ,
157
- ) {
158
- match & resolve. types [ ty] . kind {
159
- TypeDefKind :: Record ( r) => {
160
- for field in r. fields . iter ( ) {
161
- self . set_param_result_ty ( resolve, & field. ty , param, result, error)
162
- }
163
- }
164
- TypeDefKind :: Tuple ( t) => {
165
- for ty in t. types . iter ( ) {
166
- self . set_param_result_ty ( resolve, ty, param, result, error)
167
- }
168
- }
169
- TypeDefKind :: Flags ( _) => { }
170
- TypeDefKind :: Enum ( _) => { }
171
- TypeDefKind :: Variant ( v) => {
172
- for case in v. cases . iter ( ) {
173
- self . set_param_result_optional_ty (
174
- resolve,
175
- case. ty . as_ref ( ) ,
176
- param,
177
- result,
178
- error,
179
- )
180
- }
181
- }
182
- TypeDefKind :: List ( ty) | TypeDefKind :: Type ( ty) | TypeDefKind :: Option ( ty) => {
183
- self . set_param_result_ty ( resolve, ty, param, result, error)
184
- }
185
- TypeDefKind :: Result ( r) => {
186
- self . set_param_result_optional_ty ( resolve, r. ok . as_ref ( ) , param, result, error) ;
187
- self . set_param_result_optional_ty ( resolve, r. err . as_ref ( ) , param, result, result) ;
188
- }
189
- TypeDefKind :: Union ( u) => {
190
- for case in u. cases . iter ( ) {
191
- self . set_param_result_ty ( resolve, & case. ty , param, result, error)
192
- }
193
- }
194
- TypeDefKind :: Future ( ty) => {
195
- self . set_param_result_optional_ty ( resolve, ty. as_ref ( ) , param, result, error)
196
- }
197
- TypeDefKind :: Stream ( stream) => {
198
- self . set_param_result_optional_ty (
199
- resolve,
200
- stream. element . as_ref ( ) ,
201
- param,
202
- result,
203
- error,
204
- ) ;
205
- self . set_param_result_optional_ty (
206
- resolve,
207
- stream. end . as_ref ( ) ,
208
- param,
209
- result,
210
- error,
211
- ) ;
212
- }
213
- TypeDefKind :: Unknown => unreachable ! ( ) ,
214
- }
215
- }
216
-
217
- fn set_param_result_ty (
218
- & mut self ,
219
- resolve : & Resolve ,
220
- ty : & Type ,
221
- param : bool ,
222
- result : bool ,
223
- error : bool ,
224
- ) {
225
- match ty {
226
- Type :: Id ( id) => {
227
- self . type_id_info ( resolve, * id) ;
228
- let info = self . type_info . get_mut ( id) . unwrap ( ) ;
229
- if ( param && !info. param ) || ( result && !info. result ) || ( error && !info. error ) {
230
- info. param = info. param || param;
231
- info. result = info. result || result;
232
- info. error = info. error || error;
233
- self . set_param_result_id ( resolve, * id, param, result, error) ;
234
- }
235
- }
236
- _ => { }
237
- }
238
- }
239
-
240
- fn set_param_result_optional_ty (
241
- & mut self ,
242
- resolve : & Resolve ,
243
- ty : Option < & Type > ,
244
- param : bool ,
245
- result : bool ,
246
- error : bool ,
247
- ) {
248
- match ty {
249
- Some ( ty) => self . set_param_result_ty ( resolve, ty, param, result, error) ,
250
- None => ( ) ,
251
- }
252
- }
253
189
}
254
190
255
191
#[ derive( Default ) ]
0 commit comments