3333//! in the HIR, especially for multiple identifiers.
3434
3535#![ feature( array_value_iter) ]
36+ #![ feature( crate_visibility_modifier) ]
3637
3738use rustc:: arena:: Arena ;
3839use rustc:: dep_graph:: DepGraph ;
@@ -58,14 +59,13 @@ use rustc_session::config::nightly_options;
5859use rustc_session:: node_id:: NodeMap ;
5960use rustc_session:: Session ;
6061use 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 } ;
6263use rustc_span:: symbol:: { kw, sym, Symbol } ;
6364use rustc_span:: Span ;
6465use syntax:: ast;
6566use syntax:: ast:: * ;
6667use syntax:: attr;
6768use syntax:: print:: pprust;
68- use syntax:: ptr:: P as AstP ;
6969use syntax:: sess:: ParseSess ;
7070use syntax:: token:: { self , Nonterminal , Token } ;
7171use syntax:: tokenstream:: { TokenStream , TokenTree } ;
@@ -86,6 +86,7 @@ macro_rules! arena_vec {
8686
8787mod expr;
8888mod item;
89+ mod pat;
8990
9091const HIR_ID_COUNTER_LOCKED : u32 = 0xFFFFFFFF ;
9192
@@ -2636,250 +2637,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
26362637 self . expr_block ( block, AttrVec :: new ( ) )
26372638 }
26382639
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-
28832640 fn lower_anon_const ( & mut self , c : & AnonConst ) -> hir:: AnonConst {
28842641 self . with_new_scopes ( |this| hir:: AnonConst {
28852642 hir_id : this. lower_node_id ( c. id ) ,
0 commit comments