@@ -9,24 +9,33 @@ use rustc_hir::def_id::LocalDefId;
9
9
use rustc_span:: hygiene:: LocalExpnId ;
10
10
use rustc_span:: symbol:: { kw, sym, Symbol } ;
11
11
use rustc_span:: Span ;
12
- use tracing:: debug;
12
+ use tracing:: { debug, instrument } ;
13
13
14
- use crate :: { ImplTraitContext , Resolver } ;
14
+ use crate :: { ImplTraitContext , PendingAnonConstInfo , Resolver } ;
15
15
16
16
pub ( crate ) fn collect_definitions (
17
17
resolver : & mut Resolver < ' _ , ' _ > ,
18
18
fragment : & AstFragment ,
19
19
expansion : LocalExpnId ,
20
20
) {
21
- let ( parent_def, impl_trait_context, in_attr) = resolver. invocation_parents [ & expansion] ;
22
- let mut visitor = DefCollector { resolver, parent_def, expansion, impl_trait_context, in_attr } ;
21
+ let ( parent_def, pending_anon_const_info, impl_trait_context, in_attr) =
22
+ resolver. invocation_parents [ & expansion] ;
23
+ let mut visitor = DefCollector {
24
+ resolver,
25
+ parent_def,
26
+ pending_anon_const_info,
27
+ expansion,
28
+ impl_trait_context,
29
+ in_attr,
30
+ } ;
23
31
fragment. visit_with ( & mut visitor) ;
24
32
}
25
33
26
34
/// Creates `DefId`s for nodes in the AST.
27
35
struct DefCollector < ' a , ' b , ' tcx > {
28
36
resolver : & ' a mut Resolver < ' b , ' tcx > ,
29
37
parent_def : LocalDefId ,
38
+ pending_anon_const_info : Option < PendingAnonConstInfo > ,
30
39
impl_trait_context : ImplTraitContext ,
31
40
in_attr : bool ,
32
41
expansion : LocalExpnId ,
@@ -41,6 +50,17 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
41
50
span : Span ,
42
51
) -> LocalDefId {
43
52
let parent_def = self . parent_def ;
53
+ self . create_def_with_parent ( parent_def, node_id, name, def_kind, span)
54
+ }
55
+
56
+ fn create_def_with_parent (
57
+ & mut self ,
58
+ parent_def : LocalDefId ,
59
+ node_id : NodeId ,
60
+ name : Symbol ,
61
+ def_kind : DefKind ,
62
+ span : Span ,
63
+ ) -> LocalDefId {
44
64
debug ! (
45
65
"create_def(node_id={:?}, def_kind={:?}, parent_def={:?})" ,
46
66
node_id, def_kind, parent_def
@@ -110,10 +130,11 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
110
130
111
131
fn visit_macro_invoc ( & mut self , id : NodeId ) {
112
132
let id = id. placeholder_to_expn_id ( ) ;
113
- let old_parent = self
114
- . resolver
115
- . invocation_parents
116
- . insert ( id, ( self . parent_def , self . impl_trait_context , self . in_attr ) ) ;
133
+ let pending_anon_const_info = self . pending_anon_const_info . take ( ) ;
134
+ let old_parent = self . resolver . invocation_parents . insert (
135
+ id,
136
+ ( self . parent_def , pending_anon_const_info, self . impl_trait_context , self . in_attr ) ,
137
+ ) ;
117
138
assert ! ( old_parent. is_none( ) , "parent `LocalDefId` is reset for an invocation" ) ;
118
139
}
119
140
}
@@ -313,65 +334,104 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
313
334
}
314
335
}
315
336
337
+ #[ instrument( level = "debug" , skip( self ) ) ]
316
338
fn visit_anon_const ( & mut self , constant : & ' a AnonConst ) {
317
339
// HACK(min_generic_const_args): don't create defs for anon consts if we think they will
318
340
// later be turned into ConstArgKind::Path's. because this is before resolve is done, we
319
341
// may accidentally identify a construction of a unit struct as a param and not create a
320
342
// def. we'll then create a def later in ast lowering in this case. the parent of nested
321
343
// items will be messed up, but that's ok because there can't be any if we're just looking
322
344
// for bare idents.
323
- if constant. value . is_potential_trivial_const_arg ( ) {
345
+ if matches ! ( constant. value. maybe_unwrap_block( ) . kind, ExprKind :: MacCall ( ..) ) {
346
+ debug ! ( "ATTN(strict): unwrapped const is macro" ) ;
347
+ self . pending_anon_const_info = Some ( PendingAnonConstInfo {
348
+ parent_def : self . parent_def ,
349
+ id : constant. id ,
350
+ span : constant. value . span ,
351
+ } ) ;
352
+ visit:: walk_anon_const ( self , constant)
353
+ } else if constant. value . is_potential_trivial_const_arg ( ) {
354
+ debug ! ( "ATTN(strict): unwrapped const is potentially trivial" ) ;
324
355
visit:: walk_anon_const ( self , constant)
325
356
} else {
357
+ debug ! ( "ATTN(strict): unwrapped const is not trivial" ) ;
326
358
let def =
327
359
self . create_def ( constant. id , kw:: Empty , DefKind :: AnonConst , constant. value . span ) ;
328
360
self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
329
361
}
330
362
}
331
363
332
364
fn visit_expr ( & mut self , expr : & ' a Expr ) {
333
- let parent_def = match expr. kind {
334
- ExprKind :: MacCall ( ..) => return self . visit_macro_invoc ( expr. id ) ,
335
- ExprKind :: Closure ( ref closure) => {
336
- // Async closures desugar to closures inside of closures, so
337
- // we must create two defs.
338
- let closure_def = self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span ) ;
339
- match closure. coroutine_kind {
340
- Some ( coroutine_kind) => {
341
- self . with_parent ( closure_def, |this| {
342
- let coroutine_def = this. create_def (
343
- coroutine_kind. closure_id ( ) ,
344
- kw:: Empty ,
345
- DefKind :: Closure ,
346
- expr. span ,
347
- ) ;
348
- this. with_parent ( coroutine_def, |this| visit:: walk_expr ( this, expr) ) ;
349
- } ) ;
350
- return ;
351
- }
352
- None => closure_def,
353
- }
354
- }
355
- ExprKind :: Gen ( _, _, _, _) => {
356
- self . create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span )
357
- }
358
- ExprKind :: ConstBlock ( ref constant) => {
359
- for attr in & expr. attrs {
360
- visit:: walk_attribute ( self , attr) ;
361
- }
362
- let def = self . create_def (
363
- constant. id ,
365
+ if matches ! ( expr. kind, ExprKind :: MacCall ( ..) ) {
366
+ return self . visit_macro_invoc ( expr. id ) ;
367
+ }
368
+
369
+ let grandparent_def = if let Some ( pending_anon) = self . pending_anon_const_info {
370
+ debug ! ( "ATTN(lazy): pending anon={pending_anon:?} expr={expr:?}" ) ;
371
+ self . pending_anon_const_info = None ;
372
+ if !expr. is_potential_trivial_const_arg ( ) {
373
+ debug ! ( "ATTN(lazy): pending anon is not trivial" ) ;
374
+ self . create_def_with_parent (
375
+ pending_anon. parent_def ,
376
+ pending_anon. id ,
364
377
kw:: Empty ,
365
- DefKind :: InlineConst ,
366
- constant. value . span ,
367
- ) ;
368
- self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
369
- return ;
378
+ DefKind :: AnonConst ,
379
+ pending_anon. span ,
380
+ )
381
+ } else {
382
+ debug ! ( "ATTN(lazy): pending anon is potentially trivial" ) ;
383
+ self . parent_def
370
384
}
371
- _ => self . parent_def ,
385
+ } else {
386
+ self . parent_def
372
387
} ;
373
388
374
- self . with_parent ( parent_def, |this| visit:: walk_expr ( this, expr) ) ;
389
+ self . with_parent ( grandparent_def, |this| {
390
+ let parent_def = match expr. kind {
391
+ ExprKind :: Closure ( ref closure) => {
392
+ // Async closures desugar to closures inside of closures, so
393
+ // we must create two defs.
394
+ let closure_def =
395
+ this. create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span ) ;
396
+ match closure. coroutine_kind {
397
+ Some ( coroutine_kind) => {
398
+ this. with_parent ( closure_def, |this| {
399
+ let coroutine_def = this. create_def (
400
+ coroutine_kind. closure_id ( ) ,
401
+ kw:: Empty ,
402
+ DefKind :: Closure ,
403
+ expr. span ,
404
+ ) ;
405
+ this. with_parent ( coroutine_def, |this| {
406
+ visit:: walk_expr ( this, expr)
407
+ } ) ;
408
+ } ) ;
409
+ return ;
410
+ }
411
+ None => closure_def,
412
+ }
413
+ }
414
+ ExprKind :: Gen ( _, _, _, _) => {
415
+ this. create_def ( expr. id , kw:: Empty , DefKind :: Closure , expr. span )
416
+ }
417
+ ExprKind :: ConstBlock ( ref constant) => {
418
+ for attr in & expr. attrs {
419
+ visit:: walk_attribute ( this, attr) ;
420
+ }
421
+ let def = this. create_def (
422
+ constant. id ,
423
+ kw:: Empty ,
424
+ DefKind :: InlineConst ,
425
+ constant. value . span ,
426
+ ) ;
427
+ this. with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
428
+ return ;
429
+ }
430
+ _ => this. parent_def ,
431
+ } ;
432
+
433
+ this. with_parent ( parent_def, |this| visit:: walk_expr ( this, expr) )
434
+ } )
375
435
}
376
436
377
437
fn visit_ty ( & mut self , ty : & ' a Ty ) {
0 commit comments