@@ -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,10 +75,10 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
7475 self . invocation_parent . impl_trait_context = orig_itc;
7576 }
7677
77- fn with_direct_const_arg < F : FnOnce ( & mut Self ) > ( & mut self , is_direct : bool , f : F ) {
78- let orig = mem:: replace ( & mut self . invocation_parent . in_direct_const_arg , is_direct ) ;
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 ) ;
7980 f ( self ) ;
80- self . invocation_parent . in_direct_const_arg = orig;
81+ self . invocation_parent . const_arg_context = orig;
8182 }
8283
8384 fn collect_field ( & mut self , field : & ' a FieldDef , index : Option < usize > ) {
@@ -99,7 +100,10 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
99100 }
100101 }
101102
103+ #[ instrument( level = "debug" , skip( self ) ) ]
102104 fn visit_macro_invoc ( & mut self , id : NodeId ) {
105+ debug ! ( ?self . invocation_parent) ;
106+
103107 let id = id. placeholder_to_expn_id ( ) ;
104108 let old_parent = self . resolver . invocation_parents . insert ( id, self . invocation_parent ) ;
105109 assert ! ( old_parent. is_none( ) , "parent `LocalDefId` is reset for an invocation" ) ;
@@ -363,73 +367,84 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
363367 }
364368
365369 fn visit_anon_const ( & mut self , constant : & ' a AnonConst ) {
366- // `MgcaDisambiguation::Direct` is set even when MGCA is disabled, so
367- // to avoid affecting stable we have to feature gate the not creating
368- // anon consts
369- if let MgcaDisambiguation :: Direct = constant. mgca_disambiguation
370- && self . resolver . tcx . features ( ) . min_generic_const_args ( )
371- {
372- self . with_direct_const_arg ( true , |this| {
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| {
373380 visit:: walk_anon_const ( this, constant) ;
374- } ) ;
375- return ;
376- }
377-
378- self . with_direct_const_arg ( false , |this| {
379- let parent =
380- this . create_def ( constant . id , None , DefKind :: AnonConst , constant . value . span ) ;
381- this . with_parent ( parent , |this| visit :: walk_anon_const ( this , constant ) ) ;
382- } )
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+ } ;
383390 }
384391
392+ #[ instrument( level = "debug" , skip( self ) ) ]
385393 fn visit_expr ( & mut self , expr : & ' a Expr ) {
386- let handle_const_block = |this : & mut Self , constant : & ' a AnonConst , def_kind : DefKind | {
387- for attr in & expr. attrs {
388- visit:: walk_attribute ( this, attr) ;
389- }
394+ debug ! ( ?self . invocation_parent) ;
390395
391- let def = this. create_def ( constant. id , None , def_kind, constant. value . span ) ;
392- this. with_direct_const_arg ( false , |this| {
393- this. with_parent ( def, |this| visit:: walk_anon_const ( this, constant) ) ;
394- } ) ;
395- } ;
396-
397- let parent_def = match expr. kind {
396+ let parent_def = match & expr. kind {
398397 ExprKind :: MacCall ( ..) => return self . visit_macro_invoc ( expr. id ) ,
399398 ExprKind :: Closure ( ..) | ExprKind :: Gen ( ..) => {
400399 self . create_def ( expr. id , None , DefKind :: Closure , expr. span )
401400 }
402- ExprKind :: ConstBlock ( ref constant) => {
403- handle_const_block ( self , constant, DefKind :: InlineConst ) ;
404- return ;
405- }
406- ExprKind :: Struct ( ref se) if self . invocation_parent . in_direct_const_arg => {
407- let StructExpr { qself, path, fields, rest } = & * * se;
408-
409- for init_expr in fields {
410- if let ExprKind :: ConstBlock ( ref constant) = init_expr. expr . kind {
411- handle_const_block ( self , constant, DefKind :: AnonConst ) ;
412- } else {
413- visit:: walk_expr_field ( self , init_expr) ;
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) ;
414412 }
415- }
416413
417- if let Some ( qself) = qself {
418- self . visit_qself ( qself) ;
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+ } ) ;
419428 }
420- self . visit_path ( path) ;
421429
422- match rest {
423- StructRest :: Base ( expr) => self . visit_expr ( expr) ,
424- _ => ( ) ,
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) ;
425435 }
436+ } ,
426437
427- return ;
438+ _ => {
439+ return self . with_const_arg ( ConstArgContext :: NonDirect , |this| {
440+ visit:: walk_expr ( this, expr)
441+ } ) ;
428442 }
429- _ => self . invocation_parent . parent_def ,
430443 } ;
431444
432- 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+ } )
433448 }
434449
435450 fn visit_ty ( & mut self , ty : & ' a Ty ) {
0 commit comments