@@ -9,24 +9,33 @@ use rustc_hir::def_id::LocalDefId;
99use rustc_span:: hygiene:: LocalExpnId ;
1010use rustc_span:: symbol:: { kw, sym, Symbol } ;
1111use rustc_span:: Span ;
12- use tracing:: debug;
12+ use tracing:: { debug, instrument } ;
1313
14- use crate :: { ImplTraitContext , Resolver } ;
14+ use crate :: { ImplTraitContext , PendingAnonConstInfo , Resolver } ;
1515
1616pub ( crate ) fn collect_definitions (
1717 resolver : & mut Resolver < ' _ , ' _ > ,
1818 fragment : & AstFragment ,
1919 expansion : LocalExpnId ,
2020) {
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+ } ;
2331 fragment. visit_with ( & mut visitor) ;
2432}
2533
2634/// Creates `DefId`s for nodes in the AST.
2735struct DefCollector < ' a , ' b , ' tcx > {
2836 resolver : & ' a mut Resolver < ' b , ' tcx > ,
2937 parent_def : LocalDefId ,
38+ pending_anon_const_info : Option < PendingAnonConstInfo > ,
3039 impl_trait_context : ImplTraitContext ,
3140 in_attr : bool ,
3241 expansion : LocalExpnId ,
@@ -41,6 +50,17 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
4150 span : Span ,
4251 ) -> LocalDefId {
4352 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 {
4464 debug ! (
4565 "create_def(node_id={:?}, def_kind={:?}, parent_def={:?})" ,
4666 node_id, def_kind, parent_def
@@ -110,10 +130,11 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
110130
111131 fn visit_macro_invoc ( & mut self , id : NodeId ) {
112132 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+ ) ;
117138 assert ! ( old_parent. is_none( ) , "parent `LocalDefId` is reset for an invocation" ) ;
118139 }
119140}
@@ -313,65 +334,104 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
313334 }
314335 }
315336
337+ #[ instrument( level = "debug" , skip( self ) ) ]
316338 fn visit_anon_const ( & mut self , constant : & ' a AnonConst ) {
317339 // HACK(min_generic_const_args): don't create defs for anon consts if we think they will
318340 // later be turned into ConstArgKind::Path's. because this is before resolve is done, we
319341 // may accidentally identify a construction of a unit struct as a param and not create a
320342 // def. we'll then create a def later in ast lowering in this case. the parent of nested
321343 // items will be messed up, but that's ok because there can't be any if we're just looking
322344 // 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" ) ;
324355 visit:: walk_anon_const ( self , constant)
325356 } else {
357+ debug ! ( "ATTN(strict): unwrapped const is not trivial" ) ;
326358 let def =
327359 self . create_def ( constant. id , kw:: Empty , DefKind :: AnonConst , constant. value . span ) ;
328360 self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
329361 }
330362 }
331363
332364 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 ,
364377 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
370384 }
371- _ => self . parent_def ,
385+ } else {
386+ self . parent_def
372387 } ;
373388
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+ } )
375435 }
376436
377437 fn visit_ty ( & mut self , ty : & ' a Ty ) {
0 commit comments