@@ -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,61 @@ 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 stmt = self . collect_macro_call (
635
+ mac_call,
636
+ macro_ptr,
637
+ false ,
638
+ |this, expansion : Option < ast:: MacroStmts > | match expansion {
650
639
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)
659
652
}
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
+ ) ;
666
656
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
675
664
}
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 } )
682
668
} 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 } )
685
671
}
686
672
}
687
- ast:: Stmt :: Item ( _item) => { }
673
+ ast:: Stmt :: Item ( _item) => None ,
688
674
}
689
675
}
690
676
@@ -703,25 +689,27 @@ impl ExprCollector<'_> {
703
689
} ;
704
690
let prev_def_map = mem:: replace ( & mut self . expander . def_map , def_map) ;
705
691
let prev_local_module = mem:: replace ( & mut self . expander . module , module) ;
706
- let prev_statements = std:: mem:: take ( & mut self . statements_in_scope ) ;
707
692
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
713
703
} ) ;
714
704
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 ( ) ;
722
705
let syntax_node_ptr = AstPtr :: new ( & block. into ( ) ) ;
723
706
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
+ } ,
725
713
syntax_node_ptr,
726
714
) ;
727
715
@@ -903,10 +891,12 @@ impl ExprCollector<'_> {
903
891
ast:: Pat :: MacroPat ( mac) => match mac. macro_call ( ) {
904
892
Some ( call) => {
905
893
let macro_ptr = AstPtr :: new ( & call) ;
894
+ let src = self . expander . to_source ( Either :: Left ( AstPtr :: new ( & pat) ) ) ;
906
895
let pat =
907
896
self . collect_macro_call ( call, macro_ptr, true , |this, expanded_pat| {
908
897
this. collect_pat_opt_ ( expanded_pat)
909
898
} ) ;
899
+ self . source_map . pat_map . insert ( src, pat) ;
910
900
return pat;
911
901
}
912
902
None => Pat :: Missing ,
0 commit comments