Skip to content

Commit d1d9142

Browse files
GearsDatapackslpil
authored andcommitted
Document
1 parent bb6c58f commit d1d9142

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

compiler-core/src/type_/pattern.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)