@@ -16,12 +16,18 @@ pub struct Types {
1616#[ derive( Default , Clone , Copy , Debug ) ]
1717pub struct TypeInfo {
1818 /// 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 ,
2124
2225 /// 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 ,
2531
2632 /// Whether or not this type is ever used (transitively) within the
2733 /// error case in the result of a function.
@@ -33,8 +39,8 @@ pub struct TypeInfo {
3339
3440impl std:: ops:: BitOrAssign for TypeInfo {
3541 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 ;
3844 self . error |= rhs. error ;
3945 self . has_list |= rhs. has_list ;
4046 }
@@ -45,29 +51,63 @@ impl Types {
4551 for ( t, _) in resolve. types . iter ( ) {
4652 self . type_id_info ( resolve, t) ;
4753 }
48- for ( _, iface) in resolve. interfaces . iter ( ) {
49- for ( _, f) in iface. functions . iter ( ) {
50- self . type_info_func ( resolve, f) ;
51- }
52- }
5354 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+ {
5561 match item {
5662 WorldItem :: Function ( f) => {
57- self . type_info_func ( resolve, f) ;
63+ self . type_info_func ( resolve, f, import ) ;
5864 }
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 ( _) => { }
6071 }
6172 }
6273 }
6374 }
6475
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+ }
6889 }
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+ }
71111 }
72112 }
73113
@@ -146,110 +186,6 @@ impl Types {
146186 None => TypeInfo :: default ( ) ,
147187 }
148188 }
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- }
253189}
254190
255191#[ derive( Default ) ]
0 commit comments