@@ -18,7 +18,7 @@ pub(super) trait Needs<'a, 'hir> {
18
18
19
19
/// Get the need as an output.
20
20
///
21
- /// Returns `None` if `Needs::None` is set .
21
+ /// Returns `None` if not value is required .
22
22
fn try_alloc_output ( & mut self ) -> compile:: Result < Option < Output > > ;
23
23
24
24
fn assign_addr (
@@ -118,12 +118,12 @@ impl<'a, 'hir> Needs<'a, 'hir> for Address<'a, 'hir> {
118
118
119
119
#[ inline]
120
120
fn try_alloc_output ( & mut self ) -> compile:: Result < Option < Output > > {
121
- Ok ( Some ( Address :: alloc_output ( self ) ? ) )
121
+ Address :: try_alloc_output ( self )
122
122
}
123
123
124
124
#[ inline]
125
125
fn try_alloc_addr ( & mut self ) -> compile:: Result < Option < & mut Address < ' a , ' hir > > > {
126
- Ok ( Some ( Address :: alloc_addr ( self ) ? ) )
126
+ Address :: try_alloc_addr ( self )
127
127
}
128
128
129
129
#[ inline]
@@ -139,8 +139,16 @@ pub(super) enum AddressKind {
139
139
Local ,
140
140
/// The slot has been reserved, but has not been assigned to anything yet.
141
141
Dangling ,
142
- /// The address is assigned from elsewhere and *should not* be touched.
143
- Assigned ,
142
+ /// The address is assigned from elsewhere and *should not* be touched. This
143
+ /// is used for assignments.
144
+ Assign ,
145
+ /// The address is assigned from elsewhere and *should not* be touched. Once
146
+ /// it is allocated as output it will be translated into a scoped address
147
+ /// with the specified scope. So any reading from this address must be done
148
+ /// before output is allocated for it.
149
+ ///
150
+ /// The provided scope is where the assigned address was deferred from.
151
+ DeferAssign ( ScopeId ) ,
144
152
/// The address is allocated on behalf of the given scope, and we should
145
153
/// defer deallocating it until the given scope is deallocated.
146
154
Scope ( ScopeId ) ,
@@ -153,7 +161,8 @@ impl fmt::Display for AddressKind {
153
161
match self {
154
162
AddressKind :: Local => write ! ( f, "local" ) ,
155
163
AddressKind :: Dangling => write ! ( f, "dangling" ) ,
156
- AddressKind :: Assigned => write ! ( f, "assigned" ) ,
164
+ AddressKind :: Assign => write ! ( f, "assign" ) ,
165
+ AddressKind :: DeferAssign ( scope) => write ! ( f, "defer-assign({scope})" ) ,
157
166
AddressKind :: Scope ( scope) => write ! ( f, "scope({scope})" ) ,
158
167
AddressKind :: Freed => write ! ( f, "freed" ) ,
159
168
}
@@ -203,7 +212,7 @@ impl<'a, 'hir> Address<'a, 'hir> {
203
212
span,
204
213
scopes,
205
214
address : addr,
206
- kind : AddressKind :: Assigned ,
215
+ kind : AddressKind :: Assign ,
207
216
name : None ,
208
217
backtrace : Backtrace :: capture ( ) ,
209
218
}
@@ -241,25 +250,56 @@ impl<'a, 'hir> Address<'a, 'hir> {
241
250
242
251
#[ inline]
243
252
pub ( super ) fn alloc_addr ( & mut self ) -> compile:: Result < & mut Self > {
244
- if matches ! ( self . kind, AddressKind :: Dangling ) {
245
- self . kind = AddressKind :: Local ;
253
+ match self . kind {
254
+ AddressKind :: Dangling => {
255
+ self . kind = AddressKind :: Local ;
256
+ }
257
+ AddressKind :: DeferAssign ( scope) => {
258
+ self . address = self . scopes . alloc_in ( self . span , scope) ?;
259
+ self . kind = AddressKind :: Scope ( scope) ;
260
+ }
261
+ _ => { }
246
262
}
247
263
248
264
Ok ( self )
249
265
}
250
266
267
+ #[ inline]
268
+ pub ( super ) fn <
17AE
span class=pl-en>try_alloc_addr( & mut self ) -> compile:: Result < Option < & mut Self > > {
269
+ match self . kind {
270
+ AddressKind :: Dangling => {
271
+ self . kind = AddressKind :: Local ;
272
+ }
273
+ AddressKind :: DeferAssign ( ..) => {
274
+ return Ok ( None ) ;
275
+ }
276
+ _ => { }
277
+ }
278
+
279
+ Ok ( Some ( self ) )
280
+ }
281
+
251
282
#[ inline]
252
283
pub ( super ) fn alloc_output ( & mut self ) -> compile:: Result < Output > {
253
284
Ok ( self . alloc_addr ( ) ?. output ( ) )
254
285
}
255
286
287
+ #[ inline]
288
+ pub ( super ) fn try_alloc_output ( & mut self ) -> compile:: Result < Option < Output > > {
289
+ let Some ( addr) = self . try_alloc_addr ( ) ? else {
290
+ return Ok ( None ) ;
291
+ } ;
292
+
293
+ Ok ( Some ( addr. output ( ) ) )
294
+ }
295
+
256
296
#[ inline]
257
297
pub ( super ) fn output ( & self ) -> Output {
258
298
self . address . output ( )
259
299
}
260
300
261
301
pub ( super ) fn assign_addr (
262
- & self ,
302
+ & mut self ,
263
303
cx : & mut Ctxt < ' _ , ' _ , ' _ > ,
264
304
from : InstAddress ,
265
305
) -> compile:: Result < ( ) > {
@@ -459,20 +499,25 @@ impl<'a, 'hir> Any<'a, 'hir> {
459
499
cx : & mut Ctxt < ' _ , ' hir , ' _ > ,
460
500
from : InstAddress ,
461
501
) -> compile:: Result < ( ) > {
462
- match & self . kind {
463
- AnyKind :: Defer { scopes, name, .. } => {
502
+ match self . kind {
503
+ AnyKind :: Defer {
504
+ scopes,
505
+ scope,
506
+ name,
507
+ ..
508
+ } => {
464
509
self . kind = AnyKind :: Address {
465
510
address : Address {
466
511
span : self . span ,
467
512
scopes,
468
513
address : from,
469
- kind : AddressKind :: Assigned ,
470
- name : * name ,
514
+ kind : AddressKind :: DeferAssign ( scope ) ,
515
+ name,
471
516
backtrace : Backtrace :: capture ( ) ,
472
517
} ,
473
518
} ;
474
519
}
475
- AnyKind :: Address { address } => {
520
+ AnyKind :: Address { ref mut address } => {
476
521
address. assign_addr ( cx, from) ?;
477
522
}
478
523
_ => { }
@@ -502,10 +547,11 @@ impl<'a, 'hir> Any<'a, 'hir> {
502
547
self . kind = AnyKind :: Address { address } ;
503
548
}
504
549
505
- match & mut self . kind {
506
- AnyKind :: Address { address } => Ok ( Some ( address. alloc_addr ( ) ?) ) ,
507
- _ => Ok ( None ) ,
508
- }
550
+ let AnyKind :: Address { address } = & mut self . kind else {
551
+ return Ok ( None ) ;
552
+ } ;
553
+
554
+ address. try_alloc_addr ( )
509
555
}
510
556
511
557
/// Get the needs as an output.
0 commit comments