Skip to content

Commit 9eb5d95

Browse files
sbergenlpil
authored andcommitted
Allow zero-length bit array segments on JS
We were checking for a positive number, when we should be checking for non-negative instead.
1 parent 7be977b commit 9eb5d95

File tree

24 files changed

+38
-35
lines changed

24 files changed

+38
-35
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@
6565
JavaScript target.
6666
([Surya Rose](https://github.com/GearsDatapacks))
6767

68+
- Fixed a bug where a zero-length segment of a bit array would never match
69+
in a case expression on the JavaScript target.
70+
([Sakari Bergen](https://github.com/sbergen))
71+
6872
## v1.11.0-rc1 - 2025-05-15
6973

7074
### Compiler

compiler-core/src/exhaustiveness.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,7 @@ pub enum BitArrayTest {
875875
CatchAllIsBytes {
876876
size_so_far: Offset,
877877
},
878-
VariableIsPositive {
878+
VariableIsNotNegative {
879879
variable: VariableUsage,
880880
},
881881
}
@@ -893,7 +893,7 @@ impl BitArrayTest {
893893

894894
pub(crate) fn referenced_segment_patterns(&self) -> Vec<(&EcoString, &ReadAction)> {
895895
match self {
896-
BitArrayTest::VariableIsPositive { variable } => match variable {
896+
BitArrayTest::VariableIsNotNegative { variable } => match variable {
897897
VariableUsage::PatternSegment(segment_value, read_action) => {
898898
vec![(segment_value, read_action)]
899899
}
@@ -2801,17 +2801,18 @@ impl CaseToCompile {
28012801
let segment_size = segment_size(segment, &pattern_variables, None);
28022802

28032803
// If we're reading a variable number of bits we need to make sure
2804-
// that that variable is positive!
2804+
// that that variable is not negative!
28052805
if let ReadSize::VariableBits { variable, .. } = &segment_size {
28062806
match variable.as_ref() {
2807-
// If the size variable comes from reading an unsigned number
2808-
// we know that it must be positive! So we can skip checking it.
2807+
// If the size variable comes from reading an unsigned
2808+
// number we know that it can't be negative! So we can skip
2809+
// checking it.
28092810
VariableUsage::PatternSegment(_, read_action) if !read_action.signed => (),
28102811

2811-
// Otherwise we must make sure that the variable has a positive
2812-
// size.
2812+
// Otherwise we must make sure that the read size is not
2813+
// negative.
28132814
VariableUsage::PatternSegment(..) | VariableUsage::OutsideVariable(_) => tests
2814-
.push_back(BitArrayTest::VariableIsPositive {
2815+
.push_back(BitArrayTest::VariableIsNotNegative {
28152816
variable: variable.as_ref().clone(),
28162817
}),
28172818
}

compiler-core/src/javascript/decision.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,11 +1061,11 @@ impl<'generator, 'module, 'a> Variables<'generator, 'module, 'a> {
10611061
}
10621062
}
10631063

1064-
BitArrayTest::VariableIsPositive { variable } => {
1064+
BitArrayTest::VariableIsNotNegative { variable } => {
10651065
if negation.is_negated() {
1066-
docvec![self.local_var(variable.name()), " <= 0"]
1066+
docvec![self.local_var(variable.name()), " < 0"]
10671067
} else {
1068-
docvec![self.local_var(variable.name()), " > 0"]
1068+
docvec![self.local_var(variable.name()), " >= 0"]
10691069
}
10701070
}
10711071

compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__bit_arrays__case_dynamic_size_float_pattern_with_unit.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { bitArraySliceToFloat } from "../gleam.mjs";
1818

1919
function go(x) {
2020
let size = 3;
21-
if (size > 0) {
21+
if (size >= 0) {
2222
if (x.bitSize === size * 2) {
2323
if (bitArraySliceToFloat(x, 0, size * 2, true) === 1.3) {
2424
return 1;

compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__bit_arrays__case_dynamic_size_pattern_with_unit.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { bitArraySliceToInt } from "../gleam.mjs";
1818

1919
function go(x) {
2020
let size = 3;
21-
if (size > 0) {
21+
if (size >= 0) {
2222
if (x.bitSize === size * 2) {
2323
if (bitArraySliceToInt(x, 0, size * 2, true, false) === 1) {
2424
return 1;

compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__bit_arrays__case_match_dynamic_bits_size.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { bitArraySlice } from "../gleam.mjs";
1818

1919
function go(x) {
2020
let n = 16;
21-
if (n > 0) {
21+
if (n >= 0) {
2222
if (x.bitSize === n) {
2323
let a = bitArraySlice(x, 0, n);
2424
return a;

compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__bit_arrays__case_match_dynamic_bytes_size.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { bitArraySlice } from "../gleam.mjs";
1818

1919
function go(x) {
2020
let n = 3;
21-
if (n > 0) {
21+
if (n >= 0) {
2222
if (x.bitSize === n * 8) {
2323
let a = bitArraySlice(x, 0, n * 8);
2424
return a;

compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__bit_arrays__case_match_dynamic_size.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { bitArraySliceToInt } from "../gleam.mjs";
1818

1919
function go(x) {
2020
let n = 16;
21-
if (n > 0) {
21+
if (n >= 0) {
2222
if (x.bitSize === n) {
2323
let a = bitArraySliceToInt(x, 0, n, true, false);
2424
return a;

compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__bit_arrays__case_match_dynamic_size_literal_value.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { bitArraySliceToInt } from "../gleam.mjs";
1818

1919
function go(x) {
2020
let n = 8;
21-
if (n > 0) {
21+
if (n >= 0) {
2222
if (x.bitSize >= n) {
2323
if (x.bitSize === 8 + n) {
2424
if (bitArraySliceToInt(x, n, n + 8, true, false) === 21) {

compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__bit_arrays__case_match_dynamic_size_shadowed_variable.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { bitArraySliceToInt } from "../gleam.mjs";
2020
function go(x) {
2121
let n = 16;
2222
let n$1 = 5;
23-
if (n$1 > 0) {
23+
if (n$1 >= 0) {
2424
if (x.bitSize === n$1) {
2525
let a = bitArraySliceToInt(x, 0, n$1, true, false);
2626
return a;

0 commit comments

Comments
 (0)