@@ -75,6 +75,16 @@ impl PatternSource {
7575 }
7676}
7777
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+
7888/// The rib kind restricts certain accesses,
7989/// e.g. to a `Res::Local` of an outer item.
8090#[ derive( Copy , Clone , Debug ) ]
@@ -1109,7 +1119,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
11091119 }
11101120
11111121 fn resolve_params ( & mut self , params : & [ Param ] ) {
1112- let mut bindings = smallvec ! [ ( false , Default :: default ( ) ) ] ;
1122+ let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
11131123 for Param { pat, ty, .. } in params {
11141124 self . resolve_pattern ( pat, PatternSource :: FnParam , & mut bindings) ;
11151125 self . visit_ty ( ty) ;
@@ -1255,14 +1265,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
12551265
12561266 /// Arising from `source`, resolve a top level pattern.
12571267 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) ;
12591270 }
12601271
12611272 fn resolve_pattern (
12621273 & mut self ,
12631274 pat : & Pat ,
12641275 pat_src : PatternSource ,
1265- bindings : & mut SmallVec < [ ( bool , FxHashSet < Ident > ) ; 1 ] > ,
1276+ bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
12661277 ) {
12671278 self . resolve_pattern_inner ( pat, pat_src, bindings) ;
12681279 // This has to happen *after* we determine which pat_idents are variants:
@@ -1276,15 +1287,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
12761287 ///
12771288 /// A stack of sets of bindings accumulated.
12781289 ///
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.
12841294 ///
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`.
12881299 /// When each `p_i` has been dealt with, the top set is merged with its parent.
12891300 /// When a whole or-pattern has been dealt with, the thing happens.
12901301 ///
@@ -1293,7 +1304,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
12931304 & mut self ,
12941305 pat : & Pat ,
12951306 pat_src : PatternSource ,
1296- bindings : & mut SmallVec < [ ( bool , FxHashSet < Ident > ) ; 1 ] > ,
1307+ bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
12971308 ) {
12981309 // Visit all direct subpatterns of this pattern.
12991310 pat. walk ( & mut |pat| {
@@ -1317,15 +1328,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
13171328 self . smart_resolve_path ( pat. id , None , path, PathSource :: Struct ) ;
13181329 }
13191330 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
13211332 // binding already exists in this set, it should not result in an error because
13221333 // `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 ( ) ) ) ;
13241335 for p in ps {
13251336 // Now we need to switch back to a product context so that each
13261337 // part of the or-pattern internally rejects already bound names.
13271338 // 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 ( ) ) ) ;
13291340 self . resolve_pattern_inner ( p, pat_src, bindings) ;
13301341 // Move up the non-overlapping bindings to the or-pattern.
13311342 // Existing bindings just get "merged".
@@ -1352,7 +1363,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
13521363 ident : Ident ,
13531364 pat_id : NodeId ,
13541365 pat_src : PatternSource ,
1355- bindings : & mut SmallVec < [ ( bool , FxHashSet < Ident > ) ; 1 ] > ,
1366+ bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
13561367 ) -> Res {
13571368 // Add the binding to the local ribs, if it doesn't already exist in the bindings map.
13581369 // (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, '_> {
13661377 for ( is_sum, set) in bindings. iter_mut ( ) . rev ( ) {
13671378 match ( is_sum, set. get ( & ident) . cloned ( ) ) {
13681379 // 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 ,
13701381 // Already bound in an or-pattern, e.g. `V1(a) | V2(a)`.
13711382 // This is *required* for consistency which is checked later.
1372- ( true , Some ( ..) ) => already_bound_or = true ,
1383+ ( PatBoundCtx :: Or , Some ( ..) ) => already_bound_or = true ,
13731384 // Not already bound here.
13741385 _ => { }
13751386 }
0 commit comments