@@ -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,61 @@ 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 stmt = self . collect_macro_call (
635+ mac_call,
636+ macro_ptr,
637+ false ,
638+ |this, expansion : Option < ast:: MacroStmts > | match expansion {
650639 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- }
640+ let statements = expansion
641+ . statements ( )
642+ . filter_map ( |stmt| this. collect_stmt ( stmt) )
643+ . collect ( ) ;
644+ let tail = expansion. expr ( ) . map ( |expr| this. collect_expr ( expr) ) ;
645+
646+ let mac_stmts = this. alloc_expr (
647+ Expr :: MacroStmts { tail, statements } ,
648+ AstPtr :: new ( & ast:: Expr :: MacroStmts ( expansion) ) ,
649+ ) ;
650+
651+ Some ( mac_stmts)
659652 }
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- } ) ;
653+ None => None ,
654+ } ,
655+ ) ;
666656
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) ,
657+ let expr = match stmt {
658+ Some ( expr) => {
659+ // Make the macro-call point to its expanded expression so we can query
660+ // semantics on syntax pointers to the macro
661+ let src = self . expander . to_source ( syntax_ptr) ;
662+ self . source_map . expr_map . insert ( src, expr) ;
663+ expr
675664 }
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- }
665+ None => self . alloc_expr ( Expr :: Missing , syntax_ptr) ,
666+ } ;
667+ Some ( Statement :: Expr { expr, has_semi } )
682668 } else {
683- let expr = self . collect_expr_opt ( stmt . expr ( ) ) ;
684- self . statements_in_scope . push ( Statement :: Expr { expr, has_semi } ) ;
669+ let expr = self . collect_expr_opt ( expr) ;
670+ Some ( Statement :: Expr { expr, has_semi } )
685671 }
686672 }
687- ast:: Stmt :: Item ( _item) => { }
673+ ast:: Stmt :: Item ( _item) => None ,
688674 }
689675 }
690676
@@ -703,25 +689,27 @@ impl ExprCollector<'_> {
703689 } ;
704690 let prev_def_map = mem:: replace ( & mut self . expander . def_map , def_map) ;
705691 let prev_local_module = mem:: replace ( & mut self . expander . module , module) ;
706- let prev_statements = std:: mem:: take ( & mut self . statements_in_scope ) ;
707692
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 ( ( ) )
693+ let mut statements: Vec < _ > =
694+ 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+ let tail = tail. or_else ( || {
697+ let stmt = statements. pop ( ) ?;
698+ if let Statement :: Expr { expr, has_semi : false } = stmt {
699+ return Some ( expr) ;
700+ }
701+ statements. push ( stmt) ;
702+ None
713703 } ) ;
714704
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 ( ) ;
722705 let syntax_node_ptr = AstPtr :: new ( & block. into ( ) ) ;
723706 let expr_id = self . alloc_expr (
724- Expr :: Block { id : block_id, statements, tail, label : None } ,
707+ Expr :: Block {
708+ id : block_id,
709+ statements : statements. into_boxed_slice ( ) ,
710+ tail,
711+ label : None ,
712+ } ,
725713 syntax_node_ptr,
726714 ) ;
727715
@@ -903,10 +891,12 @@ impl ExprCollector<'_> {
903891 ast:: Pat :: MacroPat ( mac) => match mac. macro_call ( ) {
904892 Some ( call) => {
905893 let macro_ptr = AstPtr :: new ( & call) ;
894+ let src = self . expander . to_source ( Either :: Left ( AstPtr :: new ( & pat) ) ) ;
906895 let pat =
907896 self . collect_macro_call ( call, macro_ptr, true , |this, expanded_pat| {
908897 this. collect_pat_opt_ ( expanded_pat)
909898 } ) ;
899+ self . source_map . pat_map . insert ( src, pat) ;
910900 return pat;
911901 }
912902 None => Pat :: Missing ,
0 commit comments