@@ -34,7 +34,16 @@ pub struct PatternTyper<'a, 'b> {
3434
3535 pub error_encountered : bool ,
3636
37+ /// Variables which have been assigned in the current pattern. We can't
38+ /// register them immediately, because of the limitation described in the
39+ /// documentation for `pattern_position`.
3740 variables : Vec < Variable > ,
41+ /// Information about the current pattern being type-checked. If we're in
42+ /// a bit array, variables that are assigned in the pattern can be used as
43+ /// part of the pattern, e.g. `<<a, b:size(a)>>`. However, if we are not in
44+ /// a bit array pattern, variables cannot be used within the pattern. This
45+ /// is invalid: `#(size, <<a:size(size)>>)`. This is due to a limitation of
46+ /// Erlang.
3847 pattern_position : PatternPosition ,
3948}
4049
@@ -118,6 +127,9 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
118127 origin : origin. clone ( ) ,
119128 type_ : type_. clone ( ) ,
120129 } ) ;
130+
131+ // If we are in a bit array, we must register this variable so
132+ // it can be used in the bit array pattern itself.
121133 match self . pattern_position {
122134 PatternPosition :: BitArray => {
123135 self . environment . init_usage (
@@ -325,6 +337,7 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
325337 typed_pattern
326338 }
327339
340+ /// Register the variables bound in this pattern in the environment
328341 fn register_variables ( & mut self ) {
329342 for variable in std:: mem:: take ( & mut self . variables ) {
330343 let Variable {
@@ -346,6 +359,11 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
346359 mut segments : Vec < UntypedPatternBitArraySegment > ,
347360 location : SrcSpan ,
348361 ) -> TypedPattern {
362+ // We open a new environment scope here because any variables registered
363+ // so that they can be used inside the bit array pattern must be removed
364+ // for separate bit array patterns. `#(<<a>>, <<b:size(a)>>)` is not a
365+ // valid pattern. `a` is scoped to the first bit array pattern, until
366+ // after the pattern match is complete.
349367 let scope_reset_data = self . environment . open_new_scope ( ) ;
350368 self . pattern_position = PatternPosition :: BitArray ;
351369
@@ -362,6 +380,9 @@ impl<'a, 'b> PatternTyper<'a, 'b> {
362380 }
363381
364382 self . pattern_position = PatternPosition :: NotBitArray ;
383+ // We ignore any unused warnings here, as a pattern bound in a bit array
384+ // still has opportunities to be used after the pattern match and is not
385+ // necessarily unused just because it is not used in the pattern itself.
365386 self . environment
366387 . close_scope ( scope_reset_data, UsageTracking :: IgnoreUnused , self . problems ) ;
367388
0 commit comments