@@ -11,16 +11,17 @@ use rustc_hir::def_id::LocalDefId;
1111use rustc_middle:: span_bug;
1212use rustc_span:: hygiene:: LocalExpnId ;
1313use rustc_span:: { Span , Symbol , sym} ;
14- use tracing:: debug;
14+ use tracing:: { debug, instrument } ;
1515
16- use crate :: { ImplTraitContext , InvocationParent , Resolver } ;
16+ use crate :: { ConstArgContext , ImplTraitContext , InvocationParent , Resolver } ;
1717
1818pub ( crate ) fn collect_definitions (
1919 resolver : & mut Resolver < ' _ , ' _ > ,
2020 fragment : & AstFragment ,
2121 expansion : LocalExpnId ,
2222) {
2323 let invocation_parent = resolver. invocation_parents [ & expansion] ;
24+ debug ! ( "new fragment to visit with invocation_parent: {invocation_parent:?}" ) ;
2425 let mut visitor = DefCollector { resolver, expansion, invocation_parent } ;
2526 fragment. visit_with ( & mut visitor) ;
2627}
@@ -74,6 +75,12 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
7475 self . invocation_parent . impl_trait_context = orig_itc;
7576 }
7677
78+ fn with_const_arg < F : FnOnce ( & mut Self ) > ( & mut self , ctxt : ConstArgContext , f : F ) {
79+ let orig = mem:: replace ( & mut self . invocation_parent . const_arg_context , ctxt) ;
80+ f ( self ) ;
81+ self . invocation_parent . const_arg_context = orig;
82+ }
83+
7784 fn collect_field ( & mut self , field : & ' a FieldDef , index : Option < usize > ) {
7885 let index = |this : & Self | {
7986 index. unwrap_or_else ( || {
@@ -93,7 +100,10 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
93100 }
94101 }
95102
103+ #[ instrument( level = "debug" , skip( self ) ) ]
96104 fn visit_macro_invoc ( & mut self , id : NodeId ) {
105+ debug ! ( ?self . invocation_parent) ;
106+
97107 let id = id. placeholder_to_expn_id ( ) ;
98108 let old_parent = self . resolver . invocation_parents . insert ( id, self . invocation_parent ) ;
99109 assert ! ( old_parent. is_none( ) , "parent `LocalDefId` is reset for an invocation" ) ;
@@ -357,39 +367,84 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
357367 }
358368
359369 fn visit_anon_const ( & mut self , constant : & ' a AnonConst ) {
360- // `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so
361- // to avoid affecting stable we have to feature gate the not creating
362- // anon consts
363- if let MgcaDisambiguation :: Direct = constant. mgca_disambiguation
364- && self . resolver . tcx . features ( ) . min_generic_const_args ( )
365- {
366- visit:: walk_anon_const ( self , constant) ;
367- return ;
368- }
369-
370- let parent = self . create_def ( constant. id , None , DefKind :: AnonConst , constant. value . span ) ;
371- self . with_parent ( parent, |this| visit:: walk_anon_const ( this, constant) ) ;
370+ match constant. mgca_disambiguation {
371+ // `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so
372+ // to avoid affecting stable we have to feature gate the not creating
373+ // anon consts
374+ _ if !self . resolver . tcx . features ( ) . min_generic_const_args ( ) => {
375+ let parent =
376+ self . create_def ( constant. id , None , DefKind :: AnonConst , constant. value . span ) ;
377+ self . with_parent ( parent, |this| visit:: walk_anon_const ( this, constant) ) ;
378+ }
379+ MgcaDisambiguation :: Direct => self . with_const_arg ( ConstArgContext :: Direct , |this| {
380+ visit:: walk_anon_const ( this, constant) ;
381+ } ) ,
382+ MgcaDisambiguation :: AnonConst => {
383+ self . with_const_arg ( ConstArgContext :: NonDirect , |this| {
384+ let parent =
385+ this. create_def ( constant. id , None , DefKind :: AnonConst , constant. value . span ) ;
386+ this. with_parent ( parent, |this| visit:: walk_anon_const ( this, constant) ) ;
387+ } )
388+ }
389+ } ;
372390 }
373391
392+ #[ instrument( level = "debug" , skip( self ) ) ]
374393 fn visit_expr ( & mut self , expr : & ' a Expr ) {
375- let parent_def = match expr. kind {
394+ debug ! ( ?self . invocation_parent) ;
395+
396+ let parent_def = match & expr. kind {
376397 ExprKind :: MacCall ( ..) => return self . visit_macro_invoc ( expr. id ) ,
377398 ExprKind :: Closure ( ..) | ExprKind :: Gen ( ..) => {
378399 self . create_def ( expr. id , None , DefKind :: Closure , expr. span )
379400 }
380- ExprKind :: ConstBlock ( ref constant) => {
381- for attr in & expr. attrs {
382- visit:: walk_attribute ( self , attr) ;
401+ ExprKind :: ConstBlock ( constant) => {
402+ // Under `min_generic_const_args` a `const { }` block sometimes
403+ // corresponds to an anon const rather than an inline const.
404+ let def_kind = match self . invocation_parent . const_arg_context {
405+ ConstArgContext :: Direct => DefKind :: AnonConst ,
406+ ConstArgContext :: NonDirect => DefKind :: InlineConst ,
407+ } ;
408+
409+ return self . with_const_arg ( ConstArgContext :: NonDirect , |this| {
410+ for attr in & expr. attrs {
411+ visit:: walk_attribute ( this, attr) ;
412+ }
413+
414+ let def = this. create_def ( constant. id , None , def_kind, constant. value . span ) ;
415+ this. with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
416+ } ) ;
417+ }
418+
419+ // Avoid overwriting `const_arg_context` as we may want to treat const blocks
420+ // as being anon consts if we are inside a const argument.
421+ ExprKind :: Struct ( _) => return visit:: walk_expr ( self , expr) ,
422+ // FIXME(mgca): we may want to handle block labels in some manner
423+ ExprKind :: Block ( block, _) if let [ stmt] = block. stmts . as_slice ( ) => match stmt. kind {
424+ StmtKind :: Let ( ..) | StmtKind :: Item ( ..) | StmtKind :: Semi ( ..) | StmtKind :: Empty => {
425+ return self . with_const_arg ( ConstArgContext :: NonDirect , |this| {
426+ visit:: walk_expr ( this, expr)
427+ } ) ;
428+ }
429+
430+ // FIXME(mgca): this probably means that mac calls that expand
431+ // to semi'd const blocks are handled differently to just writing
432+ // out a semi'd const block.
433+ StmtKind :: Expr ( ..) | StmtKind :: MacCall ( ..) => {
434+ return visit:: walk_expr ( self , expr) ;
383435 }
384- let def =
385- self . create_def ( constant. id , None , DefKind :: InlineConst , constant. value . span ) ;
386- self . with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
387- return ;
436+ } ,
437+
438+ _ => {
439+ return self . with_const_arg ( ConstArgContext :: NonDirect , |this| {
440+ visit:: walk_expr ( this, expr)
441+ } ) ;
388442 }
389- _ => self . invocation_parent . parent_def ,
390443 } ;
391444
392- self . with_parent ( parent_def, |this| visit:: walk_expr ( this, expr) )
445+ self . with_const_arg ( ConstArgContext :: NonDirect , |this| {
446+ this. with_parent ( parent_def, |this| visit:: walk_expr ( this, expr) )
447+ } )
393448 }
394449
395450 fn visit_ty ( & mut self , ty : & ' a Ty ) {
0 commit comments