@@ -75,6 +75,16 @@ impl PatternSource {
75
75
}
76
76
}
77
77
78
+ /// Denotes whether the context for the set of already bound bindings is a `Product`
79
+ /// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`.
80
+ /// See those functions for more information.
81
+ enum PatBoundCtx {
82
+ /// A product pattern context, e.g., `Variant(a, b)`.
83
+ Product ,
84
+ /// An or-pattern context, e.g., `p_0 | ... | p_n`.
85
+ Or ,
86
+ }
87
+
78
88
/// The rib kind restricts certain accesses,
79
89
/// e.g. to a `Res::Local` of an outer item.
80
90
#[ derive( Copy , Clone , Debug ) ]
@@ -1109,7 +1119,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1109
1119
}
1110
1120
1111
1121
fn resolve_params ( & mut self , params : & [ Param ] ) {
1112
- let mut bindings = smallvec ! [ ( false , Default :: default ( ) ) ] ;
1122
+ let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
1113
1123
for Param { pat, ty, .. } in params {
1114
1124
self . resolve_pattern ( pat, PatternSource :: FnParam , & mut bindings) ;
1115
1125
self . visit_ty ( ty) ;
@@ -1255,14 +1265,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1255
1265
1256
1266
/// Arising from `source`, resolve a top level pattern.
1257
1267
fn resolve_pattern_top ( & mut self , pat : & Pat , pat_src : PatternSource ) {
1258
- self . resolve_pattern ( pat, pat_src, & mut smallvec ! [ ( false , Default :: default ( ) ) ] ) ;
1268
+ let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
1269
+ self . resolve_pattern ( pat, pat_src, & mut bindings) ;
1259
1270
}
1260
1271
1261
1272
fn resolve_pattern (
1262
1273
& mut self ,
1263
1274
pat : & Pat ,
1264
1275
pat_src : PatternSource ,
1265
- bindings : & mut SmallVec < [ ( bool , FxHashSet < Ident > ) ; 1 ] > ,
1276
+ bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
1266
1277
) {
1267
1278
self . resolve_pattern_inner ( pat, pat_src, bindings) ;
1268
1279
// This has to happen *after* we determine which pat_idents are variants:
@@ -1276,15 +1287,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1276
1287
///
1277
1288
/// A stack of sets of bindings accumulated.
1278
1289
///
1279
- /// In each set, `false` denotes that a found binding in it should be interpreted as
1280
- /// re-binding an already bound binding. This results in an error. Meanwhile, `true`
1281
- /// denotes that a found binding in the set should result in reusing this binding
1282
- /// rather than creating a fresh one. In other words, `false` and `true` correspond
1283
- /// to product (e.g., `(a, b)`) and sum/or contexts (e.g., `p_0 | ... | p_i`) respectively.
1290
+ /// In each set, `PatBoundCtx::Product` denotes that a found binding in it should
1291
+ /// be interpreted as re-binding an already bound binding. This results in an error.
1292
+ /// Meanwhile, `PatBound::Or` denotes that a found binding in the set should result
1293
+ /// in reusing this binding rather than creating a fresh one.
1284
1294
///
1285
- /// When called at the top level, the stack should have a single element with `false`.
1286
- /// Otherwise, pushing to the stack happens as or-patterns are encountered and the
1287
- /// context needs to be switched to `true` and then `false` for each `p_i.
1295
+ /// When called at the top level, the stack must have a single element
1296
+ /// with `PatBound::Product`. Otherwise, pushing to the stack happens as
1297
+ /// or-patterns (`p_0 | ... | p_n`) are encountered and the context needs
1298
+ /// to be switched to `PatBoundCtx::Or` and then `PatBoundCtx::Product` for each `p_i`.
1288
1299
/// When each `p_i` has been dealt with, the top set is merged with its parent.
1289
1300
/// When a whole or-pattern has been dealt with, the thing happens.
1290
1301
///
@@ -1293,7 +1304,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1293
1304
& mut self ,
1294
1305
pat : & Pat ,
1295
1306
pat_src : PatternSource ,
1296
- bindings : & mut SmallVec < [ ( bool , FxHashSet < Ident > ) ; 1 ] > ,
1307
+ bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
1297
1308
) {
1298
1309
// Visit all direct subpatterns of this pattern.
1299
1310
pat. walk ( & mut |pat| {
@@ -1317,15 +1328,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1317
1328
self . smart_resolve_path ( pat. id , None , path, PathSource :: Struct ) ;
1318
1329
}
1319
1330
PatKind :: Or ( ref ps) => {
1320
- // Add a new set of bindings to the stack. `true ` here records that when a
1331
+ // Add a new set of bindings to the stack. `Or ` here records that when a
1321
1332
// binding already exists in this set, it should not result in an error because
1322
1333
// `V1(a) | V2(a)` must be allowed and are checked for consistency later.
1323
- bindings. push ( ( true , Default :: default ( ) ) ) ;
1334
+ bindings. push ( ( PatBoundCtx :: Or , Default :: default ( ) ) ) ;
1324
1335
for p in ps {
1325
1336
// Now we need to switch back to a product context so that each
1326
1337
// part of the or-pattern internally rejects already bound names.
1327
1338
// For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad.
1328
- bindings. push ( ( false , Default :: default ( ) ) ) ;
1339
+ bindings. push ( ( PatBoundCtx :: Product , Default :: default ( ) ) ) ;
1329
1340
self . resolve_pattern_inner ( p, pat_src, bindings) ;
1330
1341
// Move up the non-overlapping bindings to the or-pattern.
1331
1342
// Existing bindings just get "merged".
@@ -1352,7 +1363,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1352
1363
ident : Ident ,
1353
1364
pat_id : NodeId ,
1354
1365
pat_src : PatternSource ,
1355
- bindings : & mut SmallVec < [ ( bool , FxHashSet < Ident > ) ; 1 ] > ,
1366
+ bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
1356
1367
) -> Res {
1357
1368
// Add the binding to the local ribs, if it doesn't already exist in the bindings map.
1358
1369
// (We must not add it if it's in the bindings map because that breaks the assumptions
@@ -1366,10 +1377,10 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
1366
1377
for ( is_sum, set) in bindings. iter_mut ( ) . rev ( ) {
1367
1378
match ( is_sum, set. get ( & ident) . cloned ( ) ) {
1368
1379
// Already bound in a product pattern, e.g. `(a, a)` which is not allowed.
1369
- ( false , Some ( ..) ) => already_bound_and = true ,
1380
+ ( PatBoundCtx :: Product , Some ( ..) ) => already_bound_and = true ,
1370
1381
// Already bound in an or-pattern, e.g. `V1(a) | V2(a)`.
1371
1382
// This is *required* for consistency which is checked later.
1372
- ( true , Some ( ..) ) => already_bound_or = true ,
1383
+ ( PatBoundCtx :: Or , Some ( ..) ) => already_bound_or = true ,
1373
1384
// Not already bound here.
1374
1385
_ => { }
1375
1386
}
0 commit comments