@@ -65,6 +65,8 @@ enum IsRepeatExpr {
65
65
Yes ,
66
66
}
67
67
68
+ struct IsNeverPattern ;
69
+
68
70
/// Describes whether an `AnonConst` is a type level const arg or
69
71
/// some other form of anon const (i.e. inline consts or enum discriminants)
70
72
#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
@@ -3182,11 +3184,15 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3182
3184
}
3183
3185
3184
3186
/// Build a map from pattern identifiers to binding-info's, and check the bindings are
3185
- /// consistent when encountering or-patterns.
3187
+ /// consistent when encountering or-patterns and never patterns .
3186
3188
/// This is done hygienically: this could arise for a macro that expands into an or-pattern
3187
3189
/// where one 'x' was from the user and one 'x' came from the macro.
3188
- fn compute_and_check_binding_map ( & mut self , pat : & Pat ) -> FxIndexMap < Ident , BindingInfo > {
3190
+ fn compute_and_check_binding_map (
3191
+ & mut self ,
3192
+ pat : & Pat ,
3193
+ ) -> Result < FxIndexMap < Ident , BindingInfo > , IsNeverPattern > {
3189
3194
let mut binding_map = FxIndexMap :: default ( ) ;
3195
+ let mut is_never_pat = false ;
3190
3196
3191
3197
pat. walk ( & mut |pat| {
3192
3198
match pat. kind {
@@ -3198,17 +3204,26 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3198
3204
PatKind :: Or ( ref ps) => {
3199
3205
// Check the consistency of this or-pattern and
3200
3206
// then add all bindings to the larger map.
3201
- let bm = self . compute_and_check_or_pat_binding_map ( ps) ;
3207
+ let ( bm , np ) = self . compute_and_check_or_pat_binding_map ( ps) ;
3202
3208
binding_map. extend ( bm) ;
3209
+ is_never_pat |= np;
3203
3210
return false ;
3204
3211
}
3212
+ PatKind :: Never => is_never_pat = true ,
3205
3213
_ => { }
3206
3214
}
3207
3215
3208
3216
true
3209
3217
} ) ;
3210
3218
3211
- binding_map
3219
+ if is_never_pat {
3220
+ for ( _, binding) in binding_map {
3221
+ self . report_error ( binding. span , ResolutionError :: BindingInNeverPattern ) ;
3222
+ }
3223
+ Err ( IsNeverPattern )
3224
+ } else {
3225
+ Ok ( binding_map)
3226
+ }
3212
3227
}
3213
3228
3214
3229
fn is_base_res_local ( & self , nid : NodeId ) -> bool {
@@ -3220,24 +3235,29 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3220
3235
3221
3236
/// Compute the binding map for an or-pattern. Checks that all of the arms in the or-pattern
3222
3237
/// have exactly the same set of bindings, with the same binding modes for each.
3223
- /// Returns the computed binding map.
3238
+ /// Returns the computed binding map and a boolean indicating whether the pattern is a never
3239
+ /// pattern.
3224
3240
fn compute_and_check_or_pat_binding_map (
3225
3241
& mut self ,
3226
3242
pats : & [ P < Pat > ] ,
3227
- ) -> FxIndexMap < Ident , BindingInfo > {
3243
+ ) -> ( FxIndexMap < Ident , BindingInfo > , bool ) {
3228
3244
let mut missing_vars = FxIndexMap :: default ( ) ;
3229
3245
let mut inconsistent_vars = FxIndexMap :: default ( ) ;
3230
3246
3231
- // 1) Compute the binding maps of all arms.
3232
- let maps =
3233
- pats. iter ( ) . map ( |pat| self . compute_and_check_binding_map ( pat) ) . collect :: < Vec < _ > > ( ) ;
3247
+ // 1) Compute the binding maps of all arms; never patterns don't participate in this.
3248
+ let not_never_pats = pats
3249
+ . iter ( )
3250
+ . filter_map ( |pat| {
3251
+ let binding_map = self . compute_and_check_binding_map ( pat) . ok ( ) ?;
3252
+ Some ( ( binding_map, pat) )
3253
+ } )
3254
+ . collect :: < Vec < _ > > ( ) ;
3234
3255
3235
3256
// 2) Record any missing bindings or binding mode inconsistencies.
3236
- for ( map_outer, pat_outer) in maps . iter ( ) . zip ( pats . iter ( ) ) {
3257
+ for ( map_outer, pat_outer) in not_never_pats . iter ( ) {
3237
3258
// Check against all arms except for the same pattern which is always self-consistent.
3238
- let inners = maps
3259
+ let inners = not_never_pats
3239
3260
. iter ( )
3240
- . zip ( pats. iter ( ) )
3241
3261
. filter ( |( _, pat) | pat. id != pat_outer. id )
3242
3262
. flat_map ( |( map, _) | map) ;
3243
3263
@@ -3285,22 +3305,17 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3285
3305
}
3286
3306
3287
3307
// 5) Bubble up the final binding map.
3308
+ let is_never_pat = not_never_pats. is_empty ( ) ;
3288
3309
let mut binding_map = FxIndexMap :: default ( ) ;
3289
- for bm in maps {
3310
+ for ( bm , _ ) in not_never_pats {
3290
3311
binding_map. extend ( bm) ;
3291
3312
}
3292
- binding_map
3313
+ ( binding_map, is_never_pat )
3293
3314
}
3294
3315
3295
- /// Check the consistency of bindings wrt or-patterns.
3316
+ /// Check the consistency of bindings wrt or-patterns and never patterns .
3296
3317
fn check_consistent_bindings ( & mut self , pat : & ' ast Pat ) {
3297
- pat. walk ( & mut |pat| match pat. kind {
3298
- PatKind :: Or ( ref ps) => {
3299
- let _ = self . compute_and_check_or_pat_binding_map ( ps) ;
3300
- false
3301
- }
3302
- _ => true ,
3303
- } )
3318
+ let _ = self . compute_and_check_binding_map ( pat) ;
3304
3319
}
3305
3320
3306
3321
fn resolve_arm ( & mut self , arm : & ' ast Arm ) {
0 commit comments