33
33
//! in the HIR, especially for multiple identifiers.
34
34
35
35
#![ feature( array_value_iter) ]
36
+ #![ feature( crate_visibility_modifier) ]
36
37
37
38
use rustc:: arena:: Arena ;
38
39
use rustc:: dep_graph:: DepGraph ;
@@ -58,14 +59,13 @@ use rustc_session::config::nightly_options;
58
59
use rustc_session:: node_id:: NodeMap ;
59
60
use rustc_session:: Session ;
60
61
use rustc_span:: hygiene:: ExpnId ;
61
- use rustc_span:: source_map:: { respan, DesugaringKind , ExpnData , ExpnKind , Spanned } ;
62
+ use rustc_span:: source_map:: { respan, DesugaringKind , ExpnData , ExpnKind } ;
62
63
use rustc_span:: symbol:: { kw, sym, Symbol } ;
63
64
use rustc_span:: Span ;
64
65
use syntax:: ast;
65
66
use syntax:: ast:: * ;
66
67
use syntax:: attr;
67
68
use syntax:: print:: pprust;
68
- use syntax:: ptr:: P as AstP ;
69
69
use syntax:: sess:: ParseSess ;
70
70
use syntax:: token:: { self , Nonterminal , Token } ;
71
71
use syntax:: tokenstream:: { TokenStream , TokenTree } ;
@@ -86,6 +86,7 @@ macro_rules! arena_vec {
86
86
87
87
mod expr;
88
88
mod item;
89
+ mod pat;
89
90
90
91
const HIR_ID_COUNTER_LOCKED : u32 = 0xFFFFFFFF ;
91
92
@@ -2636,250 +2637,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2636
2637
self . expr_block ( block, AttrVec :: new ( ) )
2637
2638
}
2638
2639
2639
- fn lower_pat ( & mut self , p : & Pat ) -> & ' hir hir:: Pat < ' hir > {
2640
- let node = match p. kind {
2641
- PatKind :: Wild => hir:: PatKind :: Wild ,
2642
- PatKind :: Ident ( ref binding_mode, ident, ref sub) => {
2643
- let lower_sub = |this : & mut Self | sub. as_ref ( ) . map ( |s| this. lower_pat ( & * s) ) ;
2644
- let node = self . lower_pat_ident ( p, binding_mode, ident, lower_sub) ;
2645
- node
2646
- }
2647
- PatKind :: Lit ( ref e) => hir:: PatKind :: Lit ( self . lower_expr ( e) ) ,
2648
- PatKind :: TupleStruct ( ref path, ref pats) => {
2649
- let qpath = self . lower_qpath (
2650
- p. id ,
2651
- & None ,
2652
- path,
2653
- ParamMode :: Optional ,
2654
- ImplTraitContext :: disallowed ( ) ,
2655
- ) ;
2656
- let ( pats, ddpos) = self . lower_pat_tuple ( pats, "tuple struct" ) ;
2657
- hir:: PatKind :: TupleStruct ( qpath, pats, ddpos)
2658
- }
2659
- PatKind :: Or ( ref pats) => {
2660
- hir:: PatKind :: Or ( self . arena . alloc_from_iter ( pats. iter ( ) . map ( |x| self . lower_pat ( x) ) ) )
2661
- }
2662
- PatKind :: Path ( ref qself, ref path) => {
2663
- let qpath = self . lower_qpath (
2664
- p. id ,
2665
- qself,
2666
- path,
2667
- ParamMode :: Optional ,
2668
- ImplTraitContext :: disallowed ( ) ,
2669
- ) ;
2670
- hir:: PatKind :: Path ( qpath)
2671
- }
2672
- PatKind :: Struct ( ref path, ref fields, etc) => {
2673
- let qpath = self . lower_qpath (
2674
- p. id ,
2675
- & None ,
2676
- path,
2677
- ParamMode :: Optional ,
2678
- ImplTraitContext :: disallowed ( ) ,
2679
- ) ;
2680
-
2681
- let fs = self . arena . alloc_from_iter ( fields. iter ( ) . map ( |f| hir:: FieldPat {
2682
- hir_id : self . next_id ( ) ,
2683
- ident : f. ident ,
2684
- pat : self . lower_pat ( & f. pat ) ,
2685
- is_shorthand : f. is_shorthand ,
2686
- span : f. span ,
2687
- } ) ) ;
2688
- hir:: PatKind :: Struct ( qpath, fs, etc)
2689
- }
2690
- PatKind :: Tuple ( ref pats) => {
2691
- let ( pats, ddpos) = self . lower_pat_tuple ( pats, "tuple" ) ;
2692
- hir:: PatKind :: Tuple ( pats, ddpos)
2693
- }
2694
- PatKind :: Box ( ref inner) => hir:: PatKind :: Box ( self . lower_pat ( inner) ) ,
2695
- PatKind :: Ref ( ref inner, mutbl) => hir:: PatKind :: Ref ( self . lower_pat ( inner) , mutbl) ,
2696
- PatKind :: Range ( ref e1, ref e2, Spanned { node : ref end, .. } ) => hir:: PatKind :: Range (
2697
- self . lower_expr ( e1) ,
2698
- self . lower_expr ( e2) ,
2699
- self . lower_range_end ( end) ,
2700
- ) ,
2701
- PatKind :: Slice ( ref pats) => self . lower_pat_slice ( pats) ,
2702
- PatKind :: Rest => {
2703
- // If we reach here the `..` pattern is not semantically allowed.
2704
- self . ban_illegal_rest_pat ( p. span )
2705
- }
2706
- PatKind :: Paren ( ref inner) => return self . lower_pat ( inner) ,
2707
- PatKind :: Mac ( _) => panic ! ( "Shouldn't exist here" ) ,
2708
- } ;
2709
-
2710
- self . pat_with_node_id_of ( p, node)
2711
- }
2712
-
2713
- fn lower_pat_tuple (
2714
- & mut self ,
2715
- pats : & [ AstP < Pat > ] ,
2716
- ctx : & str ,
2717
- ) -> ( & ' hir [ & ' hir hir:: Pat < ' hir > ] , Option < usize > ) {
2718
- let mut elems = Vec :: with_capacity ( pats. len ( ) ) ;
2719
- let mut rest = None ;
2720
-
2721
- let mut iter = pats. iter ( ) . enumerate ( ) ;
2722
- for ( idx, pat) in iter. by_ref ( ) {
2723
- // Interpret the first `..` pattern as a sub-tuple pattern.
2724
- // Note that unlike for slice patterns,
2725
- // where `xs @ ..` is a legal sub-slice pattern,
2726
- // it is not a legal sub-tuple pattern.
2727
- if pat. is_rest ( ) {
2728
- rest = Some ( ( idx, pat. span ) ) ;
2729
- break ;
2730
- }
2731
- // It was not a sub-tuple pattern so lower it normally.
2732
- elems. push ( self . lower_pat ( pat) ) ;
2733
- }
2734
-
2735
- for ( _, pat) in iter {
2736
- // There was a previous sub-tuple pattern; make sure we don't allow more...
2737
- if pat. is_rest ( ) {
2738
- // ...but there was one again, so error.
2739
- self . ban_extra_rest_pat ( pat. span , rest. unwrap ( ) . 1 , ctx) ;
2740
- } else {
2741
- elems. push ( self . lower_pat ( pat) ) ;
2742
- }
2743
- }
2744
-
2745
- ( self . arena . alloc_from_iter ( elems) , rest. map ( |( ddpos, _) | ddpos) )
2746
- }
2747
-
2748
- /// Lower a slice pattern of form `[pat_0, ..., pat_n]` into
2749
- /// `hir::PatKind::Slice(before, slice, after)`.
2750
- ///
2751
- /// When encountering `($binding_mode $ident @)? ..` (`slice`),
2752
- /// this is interpreted as a sub-slice pattern semantically.
2753
- /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`.
2754
- fn lower_pat_slice ( & mut self , pats : & [ AstP < Pat > ] ) -> hir:: PatKind < ' hir > {
2755
- let mut before = Vec :: new ( ) ;
2756
- let mut after = Vec :: new ( ) ;
2757
- let mut slice = None ;
2758
- let mut prev_rest_span = None ;
2759
-
2760
- let mut iter = pats. iter ( ) ;
2761
- // Lower all the patterns until the first occurence of a sub-slice pattern.
2762
- for pat in iter. by_ref ( ) {
2763
- match pat. kind {
2764
- // Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here.
2765
- PatKind :: Rest => {
2766
- prev_rest_span = Some ( pat. span ) ;
2767
- slice = Some ( self . pat_wild_with_node_id_of ( pat) ) ;
2768
- break ;
2769
- }
2770
- // Found a sub-slice pattern `$binding_mode $ident @ ..`.
2771
- // Record, lower it to `$binding_mode $ident @ _`, and stop here.
2772
- PatKind :: Ident ( ref bm, ident, Some ( ref sub) ) if sub. is_rest ( ) => {
2773
- prev_rest_span = Some ( sub. span ) ;
2774
- let lower_sub = |this : & mut Self | Some ( this. pat_wild_with_node_id_of ( sub) ) ;
2775
- let node = self . lower_pat_ident ( pat, bm, ident, lower_sub) ;
2776
- slice = Some ( self . pat_with_node_id_of ( pat, node) ) ;
2777
- break ;
2778
- }
2779
- // It was not a subslice pattern so lower it normally.
2780
- _ => before. push ( self . lower_pat ( pat) ) ,
2781
- }
2782
- }
2783
-
2784
- // Lower all the patterns after the first sub-slice pattern.
2785
- for pat in iter {
2786
- // There was a previous subslice pattern; make sure we don't allow more.
2787
- let rest_span = match pat. kind {
2788
- PatKind :: Rest => Some ( pat. span ) ,
2789
- PatKind :: Ident ( .., Some ( ref sub) ) if sub. is_rest ( ) => {
2790
- // The `HirValidator` is merciless; add a `_` pattern to avoid ICEs.
2791
- after. push ( self . pat_wild_with_node_id_of ( pat) ) ;
2792
- Some ( sub. span )
2793
- }
2794
- _ => None ,
2795
- } ;
2796
- if let Some ( rest_span) = rest_span {
2797
- // We have e.g., `[a, .., b, ..]`. That's no good, error!
2798
- self . ban_extra_rest_pat ( rest_span, prev_rest_span. unwrap ( ) , "slice" ) ;
2799
- } else {
2800
- // Lower the pattern normally.
2801
- after. push ( self . lower_pat ( pat) ) ;
2802
- }
2803
- }
2804
-
2805
- hir:: PatKind :: Slice (
2806
- self . arena . alloc_from_iter ( before) ,
2807
- slice,
2808
- self . arena . alloc_from_iter ( after) ,
2809
- )
2810
- }
2811
-
2812
- fn lower_pat_ident (
2813
- & mut self ,
2814
- p : & Pat ,
2815
- binding_mode : & BindingMode ,
2816
- ident : Ident ,
2817
- lower_sub : impl FnOnce ( & mut Self ) -> Option < & ' hir hir:: Pat < ' hir > > ,
2818
- ) -> hir:: PatKind < ' hir > {
2819
- match self . resolver . get_partial_res ( p. id ) . map ( |d| d. base_res ( ) ) {
2820
- // `None` can occur in body-less function signatures
2821
- res @ None | res @ Some ( Res :: Local ( _) ) => {
2822
- let canonical_id = match res {
2823
- Some ( Res :: Local ( id) ) => id,
2824
- _ => p. id ,
2825
- } ;
2826
-
2827
- hir:: PatKind :: Binding (
2828
- self . lower_binding_mode ( binding_mode) ,
2829
- self . lower_node_id ( canonical_id) ,
2830
- ident,
2831
- lower_sub ( self ) ,
2832
- )
2833
- }
2834
- Some ( res) => hir:: PatKind :: Path ( hir:: QPath :: Resolved (
2835
- None ,
2836
- self . arena . alloc ( hir:: Path {
2837
- span : ident. span ,
2838
- res : self . lower_res ( res) ,
2839
- segments : arena_vec ! [ self ; hir:: PathSegment :: from_ident( ident) ] ,
2840
- } ) ,
2841
- ) ) ,
2842
- }
2843
- }
2844
-
2845
- fn pat_wild_with_node_id_of ( & mut self , p : & Pat ) -> & ' hir hir:: Pat < ' hir > {
2846
- self . pat_with_node_id_of ( p, hir:: PatKind :: Wild )
2847
- }
2848
-
2849
- /// Construct a `Pat` with the `HirId` of `p.id` lowered.
2850
- fn pat_with_node_id_of ( & mut self , p : & Pat , kind : hir:: PatKind < ' hir > ) -> & ' hir hir:: Pat < ' hir > {
2851
- self . arena . alloc ( hir:: Pat { hir_id : self . lower_node_id ( p. id ) , kind, span : p. span } )
2852
- }
2853
-
2854
- /// Emit a friendly error for extra `..` patterns in a tuple/tuple struct/slice pattern.
2855
- fn ban_extra_rest_pat ( & self , sp : Span , prev_sp : Span , ctx : & str ) {
2856
- self . diagnostic ( )
2857
- . struct_span_err ( sp, & format ! ( "`..` can only be used once per {} pattern" , ctx) )
2858
- . span_label ( sp, & format ! ( "can only be used once per {} pattern" , ctx) )
2859
- . span_label ( prev_sp, "previously used here" )
2860
- . emit ( ) ;
2861
- }
2862
-
2863
- /// Used to ban the `..` pattern in places it shouldn't be semantically.
2864
- fn ban_illegal_rest_pat ( & self , sp : Span ) -> hir:: PatKind < ' hir > {
2865
- self . diagnostic ( )
2866
- . struct_span_err ( sp, "`..` patterns are not allowed here" )
2867
- . note ( "only allowed in tuple, tuple struct, and slice patterns" )
2868
- . emit ( ) ;
2869
-
2870
- // We're not in a list context so `..` can be reasonably treated
2871
- // as `_` because it should always be valid and roughly matches the
2872
- // intent of `..` (notice that the rest of a single slot is that slot).
2873
- hir:: PatKind :: Wild
2874
- }
2875
-
2876
- fn lower_range_end ( & mut self , e : & RangeEnd ) -> hir:: RangeEnd {
2877
- match * e {
2878
- RangeEnd :: Included ( _) => hir:: RangeEnd :: Included ,
2879
- RangeEnd :: Excluded => hir:: RangeEnd :: Excluded ,
2880
- }
2881
- }
2882
-
2883
2640
fn lower_anon_const ( & mut self , c : & AnonConst ) -> hir:: AnonConst {
2884
2641
self . with_new_scopes ( |this| hir:: AnonConst {
2885
2642
hir_id : this. lower_node_id ( c. id ) ,
0 commit comments