@@ -13,7 +13,6 @@ use hir_expand::{
1313use la_arena:: Arena ;
1414use profile:: Count ;
1515use rustc_hash:: FxHashMap ;
16- use smallvec:: smallvec;
1716use syntax:: {
1817 ast:: {
1918 self , ArrayExprKind , AstChildren , HasArgList , HasLoopBody , HasName , LiteralKind ,
@@ -97,7 +96,6 @@ pub(super) fn lower(
9796 or_pats : Default :: default ( ) ,
9897 } ,
9998 expander,
100- statements_in_scope : Vec :: new ( ) ,
10199 name_to_pat_grouping : Default :: default ( ) ,
102100 is_lowering_inside_or_pat : false ,
103101 }
@@ -109,7 +107,6 @@ struct ExprCollector<'a> {
109107 expander : Expander ,
110108 body : Body ,
111109 source_map : BodySourceMap ,
112- statements_in_scope : Vec < Statement > ,
113110 // a poor-mans union-find?
114111 name_to_pat_grouping : FxHashMap < Name , Vec < PatId > > ,
115112 is_lowering_inside_or_pat : bool ,
@@ -514,27 +511,25 @@ impl ExprCollector<'_> {
514511 ast:: Expr :: MacroExpr ( e) => {
515512 let e = e. macro_call ( ) ?;
516513 let macro_ptr = AstPtr :: new ( & e) ;
517- let id = self . collect_macro_call ( e, macro_ptr. clone ( ) , true , |this, expansion| {
514+ let id = self . collect_macro_call ( e, macro_ptr, true , |this, expansion| {
518515 expansion. map ( |it| this. collect_expr ( it) )
519516 } ) ;
520517 match id {
521518 Some ( id) => {
522- self . source_map
523- . macro_call_to_exprs
524- . insert ( self . expander . to_source ( macro_ptr) , smallvec ! [ id] ) ;
519+ // Make the macro-call point to its expanded expression so we can query
520+ // semantics on syntax pointers to the macro
521+ let src = self . expander . to_source ( syntax_ptr) ;
522+ self . source_map . expr_map . insert ( src, id) ;
525523 id
526524 }
527- None => self . alloc_expr ( Expr :: Missing , syntax_ptr. clone ( ) ) ,
525+ None => self . alloc_expr ( Expr :: Missing , syntax_ptr) ,
528526 }
529527 }
530528 ast:: Expr :: MacroStmts ( e) => {
531- e. statements ( ) . for_each ( |s| self . collect_stmt ( s) ) ;
532- let tail = e
533- . expr ( )
534- . map ( |e| self . collect_expr ( e) )
535- . unwrap_or_else ( || self . alloc_expr ( Expr :: Missing , syntax_ptr. clone ( ) ) ) ;
529+ let statements = e. statements ( ) . filter_map ( |s| self . collect_stmt ( s) ) . collect ( ) ;
530+ let tail = e. expr ( ) . map ( |e| self . collect_expr ( e) ) ;
536531
537- self . alloc_expr ( Expr :: MacroStmts { tail } , syntax_ptr)
532+ self . alloc_expr ( Expr :: MacroStmts { tail, statements } , syntax_ptr)
538533 }
539534 ast:: Expr :: UnderscoreExpr ( _) => self . alloc_expr ( Expr :: Underscore , syntax_ptr) ,
540535 } )
@@ -607,11 +602,11 @@ impl ExprCollector<'_> {
607602 }
608603 }
609604
610- fn collect_stmt ( & mut self , s : ast:: Stmt ) {
605+ fn collect_stmt ( & mut self , s : ast:: Stmt ) -> Option < Statement > {
611606 match s {
612607 ast:: Stmt :: LetStmt ( stmt) => {
613608 if self . check_cfg ( & stmt) . is_none ( ) {
614- return ;
609+ return None ;
615610 }
616611 let pat = self . collect_pat_opt ( stmt. pat ( ) ) ;
617612 let type_ref =
@@ -621,70 +616,62 @@ impl ExprCollector<'_> {
621616 . let_else ( )
622617 . and_then ( |let_else| let_else. block_expr ( ) )
623618 . map ( |block| self . collect_block ( block) ) ;
624- self . statements_in_scope . push ( Statement :: Let {
625- pat,
626- type_ref,
627- initializer,
628- else_branch,
629- } ) ;
619+ Some ( Statement :: Let { pat, type_ref, initializer, else_branch } )
630620 }
631621 ast:: Stmt :: ExprStmt ( stmt) => {
632- if let Some ( expr) = stmt. expr ( ) {
633- if self . check_cfg ( & expr) . is_none ( ) {
634- return ;
622+ let expr = stmt. expr ( ) ;
623+ if let Some ( expr) = & expr {
624+ if self . check_cfg ( expr) . is_none ( ) {
625+ return None ;
635626 }
636627 }
637628 let has_semi = stmt. semicolon_token ( ) . is_some ( ) ;
638- // Note that macro could be expended to multiple statements
639- if let Some ( ast:: Expr :: MacroExpr ( e) ) = stmt. expr ( ) {
640- let m = match e. macro_call ( ) {
641- Some ( it) => it,
642- None => return ,
643- } ;
644- let macro_ptr = AstPtr :: new ( & m) ;
645- let syntax_ptr = AstPtr :: new ( & stmt. expr ( ) . unwrap ( ) ) ;
646-
647- let prev_stmt = self . statements_in_scope . len ( ) ;
648- self . collect_macro_call ( m, macro_ptr. clone ( ) , false , |this, expansion| {
649- match expansion {
629+ // Note that macro could be expanded to multiple statements
630+ if let Some ( expr @ ast:: Expr :: MacroExpr ( mac) ) = & expr {
631+ let mac_call = mac. macro_call ( ) ?;
632+ let syntax_ptr = AstPtr :: new ( expr) ;
633+ let macro_ptr = AstPtr :: new ( & mac_call) ;
634+ // let prev_stmt = self.statements_in_scope.len();
635+ let stmt = self . collect_macro_call (
636+ mac_call,
637+ macro_ptr,
638+ false ,
639+ |this, expansion : Option < ast:: MacroStmts > | match expansion {
650640 Some ( expansion) => {
651- let statements: ast:: MacroStmts = expansion;
652-
653- statements. statements ( ) . for_each ( |stmt| this. collect_stmt ( stmt) ) ;
654- if let Some ( expr) = statements. expr ( ) {
655- let expr = this. collect_expr ( expr) ;
656- this. statements_in_scope
657- . push ( Statement :: Expr { expr, has_semi } ) ;
658- }
641+ let statements = expansion
642+ . statements ( )
643+ . filter_map ( |stmt| this. collect_stmt ( stmt) )
644+ . collect ( ) ;
645+ let tail = expansion. expr ( ) . map ( |expr| this. collect_expr ( expr) ) ;
646+
647+ let mac_stmts = this. alloc_expr (
648+ Expr :: MacroStmts { tail, statements } ,
649+ AstPtr :: new ( & ast:: Expr :: MacroStmts ( expansion) ) ,
650+ ) ;
651+
652+ Some ( mac_stmts)
659653 }
660- None => {
661- let expr = this. alloc_expr ( Expr :: Missing , syntax_ptr. clone ( ) ) ;
662- this. statements_in_scope . push ( Statement :: Expr { expr, has_semi } ) ;
663- }
664- }
665- } ) ;
654+ None => None ,
655+ } ,
656+ ) ;
666657
667- let mut macro_exprs = smallvec ! [ ] ;
668- for stmt in & self . statements_in_scope [ prev_stmt..] {
669- match * stmt {
670- Statement :: Let { initializer, else_branch, .. } => {
671- macro_exprs. extend ( initializer) ;
672- macro_exprs. extend ( else_branch) ;
673- }
674- Statement :: Expr { expr, .. } => macro_exprs. push ( expr) ,
658+ let expr = match stmt {
659+ Some ( expr) => {
660+ // Make the macro-call point to its expanded expression so we can query
661+ // semantics on syntax pointers to the macro
662+ let src = self . expander . to_source ( syntax_ptr) ;
663+ self . source_map . expr_map . insert ( src, expr) ;
664+ expr
675665 }
676- }
677- if !macro_exprs. is_empty ( ) {
678- self . source_map
679- . macro_call_to_exprs
680- . insert ( self . expander . to_source ( macro_ptr) , macro_exprs) ;
681- }
666+ None => self . alloc_expr ( Expr :: Missing , syntax_ptr) ,
667+ } ;
668+ Some ( Statement :: Expr { expr, has_semi } )
682669 } else {
683- let expr = self . collect_expr_opt ( stmt . expr ( ) ) ;
684- self . statements_in_scope . push ( Statement :: Expr { expr, has_semi } ) ;
670+ let expr = self . collect_expr_opt ( expr) ;
671+ Some ( Statement :: Expr { expr, has_semi } )
685672 }
686673 }
687- ast:: Stmt :: Item ( _item) => { }
674+ ast:: Stmt :: Item ( _item) => None ,
688675 }
689676 }
690677
@@ -703,22 +690,10 @@ impl ExprCollector<'_> {
703690 } ;
704691 let prev_def_map = mem:: replace ( & mut self . expander . def_map , def_map) ;
705692 let prev_local_module = mem:: replace ( & mut self . expander . module , module) ;
706- let prev_statements = std:: mem:: take ( & mut self . statements_in_scope ) ;
707-
708- block. statements ( ) . for_each ( |s| self . collect_stmt ( s) ) ;
709- block. tail_expr ( ) . and_then ( |e| {
710- let expr = self . maybe_collect_expr ( e) ?;
711- self . statements_in_scope . push ( Statement :: Expr { expr, has_semi : false } ) ;
712- Some ( ( ) )
713- } ) ;
714-
715- let mut tail = None ;
716- if let Some ( Statement :: Expr { expr, has_semi : false } ) = self . statements_in_scope . last ( ) {
717- tail = Some ( * expr) ;
718- self . statements_in_scope . pop ( ) ;
719- }
720- let tail = tail;
721- let statements = std:: mem:: replace ( & mut self . statements_in_scope , prev_statements) . into ( ) ;
693+
694+ let statements = block. statements ( ) . filter_map ( |s| self . collect_stmt ( s) ) . collect ( ) ;
695+ let tail = block. tail_expr ( ) . and_then ( |e| self . maybe_collect_expr ( e) ) ;
696+
722697 let syntax_node_ptr = AstPtr :: new ( & block. into ( ) ) ;
723698 let expr_id = self . alloc_expr (
724699 Expr :: Block { id : block_id, statements, tail, label : None } ,
@@ -903,10 +878,12 @@ impl ExprCollector<'_> {
903878 ast:: Pat :: MacroPat ( mac) => match mac. macro_call ( ) {
904879 Some ( call) => {
905880 let macro_ptr = AstPtr :: new ( & call) ;
881+ let src = self . expander . to_source ( Either :: Left ( AstPtr :: new ( & pat) ) ) ;
906882 let pat =
907883 self . collect_macro_call ( call, macro_ptr, true , |this, expanded_pat| {
908884 this. collect_pat_opt_ ( expanded_pat)
909885 } ) ;
886+ self . source_map . pat_map . insert ( src, pat) ;
910887 return pat;
911888 }
912889 None => Pat :: Missing ,
0 commit comments