@@ -65,6 +65,8 @@ enum IsRepeatExpr {
6565 Yes ,
6666}
6767
68+ struct IsNeverPattern ;
69+
6870/// Describes whether an `AnonConst` is a type level const arg or
6971/// some other form of anon const (i.e. inline consts or enum discriminants)
7072#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
@@ -3191,11 +3193,15 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
31913193 }
31923194
31933195 /// Build a map from pattern identifiers to binding-info's, and check the bindings are
3194- /// consistent when encountering or-patterns.
3196+ /// consistent when encountering or-patterns and never patterns .
31953197 /// This is done hygienically: this could arise for a macro that expands into an or-pattern
31963198 /// where one 'x' was from the user and one 'x' came from the macro.
3197- fn compute_and_check_binding_map ( & mut self , pat : & Pat ) -> FxIndexMap < Ident , BindingInfo > {
3199+ fn compute_and_check_binding_map (
3200+ & mut self ,
3201+ pat : & Pat ,
3202+ ) -> Result < FxIndexMap < Ident , BindingInfo > , IsNeverPattern > {
31983203 let mut binding_map = FxIndexMap :: default ( ) ;
3204+ let mut is_never_pat = false ;
31993205
32003206 pat. walk ( & mut |pat| {
32013207 match pat. kind {
@@ -3207,17 +3213,26 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32073213 PatKind :: Or ( ref ps) => {
32083214 // Check the consistency of this or-pattern and
32093215 // then add all bindings to the larger map.
3210- let bm = self . compute_and_check_or_pat_binding_map ( ps) ;
3216+ let ( bm , np ) = self . compute_and_check_or_pat_binding_map ( ps) ;
32113217 binding_map. extend ( bm) ;
3218+ is_never_pat |= np;
32123219 return false ;
32133220 }
3221+ PatKind :: Never => is_never_pat = true ,
32143222 _ => { }
32153223 }
32163224
32173225 true
32183226 } ) ;
32193227
3220- binding_map
3228+ if is_never_pat {
3229+ for ( _, binding) in binding_map {
3230+ self . report_error ( binding. span , ResolutionError :: BindingInNeverPattern ) ;
3231+ }
3232+ Err ( IsNeverPattern )
3233+ } else {
3234+ Ok ( binding_map)
3235+ }
32213236 }
32223237
32233238 fn is_base_res_local ( & self , nid : NodeId ) -> bool {
@@ -3229,24 +3244,29 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32293244
32303245 /// Compute the binding map for an or-pattern. Checks that all of the arms in the or-pattern
32313246 /// have exactly the same set of bindings, with the same binding modes for each.
3232- /// Returns the computed binding map.
3247+ /// Returns the computed binding map and a boolean indicating whether the pattern is a never
3248+ /// pattern.
32333249 fn compute_and_check_or_pat_binding_map (
32343250 & mut self ,
32353251 pats : & [ P < Pat > ] ,
3236- ) -> FxIndexMap < Ident , BindingInfo > {
3252+ ) -> ( FxIndexMap < Ident , BindingInfo > , bool ) {
32373253 let mut missing_vars = FxIndexMap :: default ( ) ;
32383254 let mut inconsistent_vars = FxIndexMap :: default ( ) ;
32393255
3240- // 1) Compute the binding maps of all arms.
3241- let maps =
3242- pats. iter ( ) . map ( |pat| self . compute_and_check_binding_map ( pat) ) . collect :: < Vec < _ > > ( ) ;
3256+ // 1) Compute the binding maps of all arms; never patterns don't participate in this.
3257+ let not_never_pats = pats
3258+ . iter ( )
3259+ . filter_map ( |pat| {
3260+ let binding_map = self . compute_and_check_binding_map ( pat) . ok ( ) ?;
3261+ Some ( ( binding_map, pat) )
3262+ } )
3263+ . collect :: < Vec < _ > > ( ) ;
32433264
32443265 // 2) Record any missing bindings or binding mode inconsistencies.
3245- for ( map_outer, pat_outer) in maps . iter ( ) . zip ( pats . iter ( ) ) {
3266+ for ( map_outer, pat_outer) in not_never_pats . iter ( ) {
32463267 // Check against all arms except for the same pattern which is always self-consistent.
3247- let inners = maps
3268+ let inners = not_never_pats
32483269 . iter ( )
3249- . zip ( pats. iter ( ) )
32503270 . filter ( |( _, pat) | pat. id != pat_outer. id )
32513271 . flat_map ( |( map, _) | map) ;
32523272
@@ -3294,22 +3314,17 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32943314 }
32953315
32963316 // 5) Bubble up the final binding map.
3317+ let is_never_pat = not_never_pats. is_empty ( ) ;
32973318 let mut binding_map = FxIndexMap :: default ( ) ;
3298- for bm in maps {
3319+ for ( bm , _ ) in not_never_pats {
32993320 binding_map. extend ( bm) ;
33003321 }
3301- binding_map
3322+ ( binding_map, is_never_pat )
33023323 }
33033324
3304- /// Check the consistency of bindings wrt or-patterns.
3325+ /// Check the consistency of bindings wrt or-patterns and never patterns .
33053326 fn check_consistent_bindings ( & mut self , pat : & ' ast Pat ) {
3306- pat. walk ( & mut |pat| match pat. kind {
3307- PatKind :: Or ( ref ps) => {
3308- let _ = self . compute_and_check_or_pat_binding_map ( ps) ;
3309- false
3310- }
3311- _ => true ,
3312- } )
3327+ let _ = self . compute_and_check_binding_map ( pat) ;
33133328 }
33143329
33153330 fn resolve_arm ( & mut self , arm : & ' ast Arm ) {
0 commit comments