@@ -13,7 +13,6 @@ use hir_expand::{
13
13
use la_arena:: Arena ;
14
14
use profile:: Count ;
15
15
use rustc_hash:: FxHashMap ;
16
- use smallvec:: smallvec;
17
16
use syntax:: {
18
17
ast:: {
19
18
self , ArrayExprKind , AstChildren , HasArgList , HasLoopBody , HasName , LiteralKind ,
@@ -97,7 +96,6 @@ pub(super) fn lower(
97
96
or_pats : Default :: default ( ) ,
98
97
} ,
99
98
expander,
100
- statements_in_scope : Vec :: new ( ) ,
101
99
name_to_pat_grouping : Default :: default ( ) ,
102
100
is_lowering_inside_or_pat : false ,
103
101
}
@@ -109,7 +107,6 @@ struct ExprCollector<'a> {
109
107
expander : Expander ,
110
108
body : Body ,
111
109
source_map : BodySourceMap ,
112
- statements_in_scope : Vec < Statement > ,
113
110
// a poor-mans union-find?
114
111
name_to_pat_grouping : FxHashMap < Name , Vec < PatId > > ,
115
112
is_lowering_inside_or_pat : bool ,
@@ -514,27 +511,25 @@ impl ExprCollector<'_> {
514
511
ast:: Expr :: MacroExpr ( e) => {
515
512
let e = e. macro_call ( ) ?;
516
513
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| {
518
515
expansion. map ( |it| this. collect_expr ( it) )
519
516
} ) ;
520
517
match id {
521
518
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) ;
525
523
id
526
524
}
527
- None => self . alloc_expr ( Expr :: Missing , syntax_ptr. clone ( ) ) ,
525
+ None => self . alloc_expr ( Expr :: Missing , syntax_ptr) ,
528
526
}
529
527
}
530
528
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) ) ;
536
531
537
- self . alloc_expr ( Expr :: MacroStmts { tail } , syntax_ptr)
532
+ self . alloc_expr ( Expr :: MacroStmts { tail, statements } , syntax_ptr)
538
533
}
539
534
ast:: Expr :: UnderscoreExpr ( _) => self . alloc_expr ( Expr :: Underscore , syntax_ptr) ,
540
535
} )
@@ -607,11 +602,11 @@ impl ExprCollector<'_> {
607
602
}
608
603
}
609
604
610
- fn collect_stmt ( & mut self , s : ast:: Stmt ) {
605
+ fn collect_stmt ( & mut self , s : ast:: Stmt ) -> Option < Statement > {
611
606
match s {
612
607
ast:: Stmt :: LetStmt ( stmt) => {
613
608
if self . check_cfg ( & stmt) . is_none ( ) {
614
- return ;
609
+ return None ;
615
610
}
616
611
let pat = self . collect_pat_opt ( stmt. pat ( ) ) ;
617
612
let type_ref =
@@ -621,70 +616,62 @@ impl ExprCollector<'_> {
621
616
. let_else ( )
622
617
. and_then ( |let_else| let_else. block_expr ( ) )
623
618
. 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 } )
630
620
}
631
621
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 ;
635
626
}
636
627
}
637
628
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 {
650
640
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)
659
653
}
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
+ ) ;
666
657
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
675
665
}
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 } )
682
669
} 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 } )
685
672
}
686
673
}
687
- ast:: Stmt :: Item ( _item) => { }
674
+ ast:: Stmt :: Item ( _item) => None ,
688
675
}
689
676
}
690
677
@@ -703,22 +690,10 @@ impl ExprCollector<'_> {
703
690
} ;
704
691
let prev_def_map = mem:: replace ( & mut self . expander . def_map , def_map) ;
705
692
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
+
722
697
let syntax_node_ptr = AstPtr :: new ( & block. into ( ) ) ;
723
698
let expr_id = self . alloc_expr (
724
699
Expr :: Block { id : block_id, statements, tail, label : None } ,
@@ -903,10 +878,12 @@ impl ExprCollector<'_> {
903
878
ast:: Pat :: MacroPat ( mac) => match mac. macro_call ( ) {
904
879
Some ( call) => {
905
880
let macro_ptr = AstPtr :: new ( & call) ;
881
+ let src = self . expander . to_source ( Either :: Left ( AstPtr :: new ( & pat) ) ) ;
906
882
let pat =
907
883
self . collect_macro_call ( call, macro_ptr, true , |this, expanded_pat| {
908
884
this. collect_pat_opt_ ( expanded_pat)
909
885
} ) ;
886
+ self . source_map . pat_map . insert ( src, pat) ;
910
887
return pat;
911
888
}
912
889
None => Pat :: Missing ,
0 commit comments