1+ use std:: ops:: DerefMut ;
2+
13use rustc_ast:: mut_visit:: * ;
24use rustc_ast:: ptr:: P ;
35use rustc_ast:: token:: Delimiter ;
@@ -12,20 +14,21 @@ use thin_vec::ThinVec;
1214use crate :: expand:: { AstFragment , AstFragmentKind } ;
1315
1416pub ( crate ) fn placeholder (
15- kind : AstFragmentKind ,
17+ is_bang_brace : bool ,
18+ fragment_kind : AstFragmentKind ,
1619 id : ast:: NodeId ,
1720 vis : Option < ast:: Visibility > ,
1821) -> AstFragment {
19- fn mac_placeholder ( ) -> P < ast:: MacCall > {
22+ let mac_placeholder = || -> P < ast:: MacCall > {
2023 P ( ast:: MacCall {
2124 path : ast:: Path { span : DUMMY_SP , segments : ThinVec :: new ( ) , tokens : None } ,
2225 args : P ( ast:: DelimArgs {
2326 dspan : ast:: tokenstream:: DelimSpan :: dummy ( ) ,
24- delim : Delimiter :: Parenthesis ,
27+ delim : if is_bang_brace { Delimiter :: Brace } else { Delimiter :: Parenthesis } ,
2528 tokens : ast:: tokenstream:: TokenStream :: new ( Vec :: new ( ) ) ,
2629 } ) ,
2730 } )
28- }
31+ } ;
2932
3033 let ident = Ident :: empty ( ) ;
3134 let attrs = ast:: AttrVec :: new ( ) ;
@@ -49,7 +52,7 @@ pub(crate) fn placeholder(
4952 let pat =
5053 || P ( ast:: Pat { id, kind : ast:: PatKind :: MacCall ( mac_placeholder ( ) ) , span, tokens : None } ) ;
5154
52- match kind {
55+ match fragment_kind {
5356 AstFragmentKind :: Crate => AstFragment :: Crate ( ast:: Crate {
5457 attrs : Default :: default ( ) ,
5558 items : Default :: default ( ) ,
@@ -194,6 +197,7 @@ pub(crate) fn placeholder(
194197#[ derive( Default ) ]
195198pub ( crate ) struct PlaceholderExpander {
196199 expanded_fragments : FxHashMap < ast:: NodeId , AstFragment > ,
200+ expr_under_let_init_else : bool ,
197201}
198202
199203impl PlaceholderExpander {
@@ -301,8 +305,48 @@ impl MutVisitor for PlaceholderExpander {
301305 }
302306 }
303307
308+ fn visit_local ( & mut self , local : & mut P < ast:: Local > ) {
309+ let ast:: Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local. deref_mut ( ) ;
310+ self . visit_id ( id) ;
311+ for attr in attrs. iter_mut ( ) {
312+ self . visit_attribute ( attr) ;
313+ }
314+ self . visit_pat ( pat) ;
315+ if let Some ( ty) = ty {
316+ self . visit_ty ( ty) ;
317+ }
318+ match kind {
319+ ast:: LocalKind :: Decl => { }
320+ ast:: LocalKind :: Init ( init) => {
321+ self . visit_expr ( init) ;
322+ }
323+ ast:: LocalKind :: InitElse ( init, els) => {
324+ self . expr_under_let_init_else = true ;
325+ self . visit_expr ( init) ;
326+ self . expr_under_let_init_else = false ;
327+ self . visit_block ( els) ;
328+ }
329+ }
330+ visit_lazy_tts ( self , tokens) ;
331+ if let Some ( sp) = colon_sp {
332+ self . visit_span ( sp) ;
333+ }
334+ self . visit_span ( span) ;
335+ }
336+
304337 fn visit_expr ( & mut self , expr : & mut P < ast:: Expr > ) {
305- match expr. kind {
338+ tracing:: debug!( "visit: {:?}" , expr) ;
339+ match & mut expr. kind {
340+ ast:: ExprKind :: Paren ( paren) => {
341+ if self . expr_under_let_init_else
342+ && let ast:: ExprKind :: MacCall ( mac) = & paren. kind
343+ && matches ! ( mac. args. delim, Delimiter :: Brace )
344+ {
345+ * expr = self . remove ( paren. id ) . make_expr ( ) ;
346+ } else {
347+ walk_expr ( self , expr) ;
348+ }
349+ }
306350 ast:: ExprKind :: MacCall ( _) => * expr = self . remove ( expr. id ) . make_expr ( ) ,
307351 _ => walk_expr ( self , expr) ,
308352 }
0 commit comments