+4
CHANGELOG.md
+4
CHANGELOG.md
···
184
184
"Extract variable" code action was used on a `use` expression.
185
185
([Surya Rose](https://github.com/GearsDatapacks))
186
186
187
+
- Fixed a bug where the compiler would crash when using the `utf8_codepoint`
188
+
bit array segment on the JavaScript target.
189
+
([Surya Rose](https://github.com/GearsDatapacks))
190
+
187
191
## v1.11.1 - 2025-06-05
188
192
189
193
### Compiler
+61
-8
compiler-core/src/bit_array.rs
+61
-8
compiler-core/src/bit_array.rs
···
2
2
use num_bigint::BigInt;
3
3
4
4
use crate::ast::{self, BitArrayOption, SrcSpan};
5
+
use crate::build::Target;
5
6
use crate::type_::Type;
6
7
use std::sync::Arc;
7
8
···
11
12
12
13
pub fn type_options_for_value<TypedValue>(
13
14
input_options: &[BitArrayOption<TypedValue>],
15
+
target: Target,
14
16
) -> Result<Arc<Type>, Error>
15
17
where
16
18
TypedValue: GetLiteralValue,
17
19
{
18
-
type_options(input_options, TypeOptionsMode::Expression, false)
20
+
type_options(input_options, TypeOptionsMode::Expression, false, target)
19
21
}
20
22
21
23
pub fn type_options_for_pattern<TypedValue>(
22
24
input_options: &[BitArrayOption<TypedValue>],
23
25
must_have_size: bool,
26
+
target: Target,
24
27
) -> Result<Arc<Type>, Error>
25
28
where
26
29
TypedValue: GetLiteralValue,
27
30
{
28
-
type_options(input_options, TypeOptionsMode::Pattern, must_have_size)
31
+
type_options(
32
+
input_options,
33
+
TypeOptionsMode::Pattern,
34
+
must_have_size,
35
+
target,
36
+
)
29
37
}
30
38
31
39
struct SegmentOptionCategories<'a, T> {
···
86
94
input_options: &[BitArrayOption<TypedValue>],
87
95
mode: TypeOptionsMode,
88
96
must_have_size: bool,
97
+
target: Target,
89
98
) -> Result<Arc<Type>, Error>
90
99
where
91
100
TypedValue: GetLiteralValue,
···
96
105
// Basic category checking
97
106
for option in input_options {
98
107
match option {
108
+
Utf8Codepoint { .. } | Utf16Codepoint { .. } | Utf32Codepoint { .. }
109
+
if mode == TypeOptionsMode::Pattern && target == Target::JavaScript =>
110
+
{
111
+
return err(
112
+
ErrorType::OptionNotSupportedForTarget {
113
+
target,
114
+
option: UnsupportedOption::UtfCodepointPattern,
115
+
},
116
+
option.location(),
117
+
);
118
+
}
119
+
99
120
Bytes { .. }
100
121
| Int { .. }
101
122
| Float { .. }
···
129
150
} else {
130
151
categories.signed = Some(option);
131
152
}
153
+
}
154
+
155
+
Native { .. } if target == Target::JavaScript => {
156
+
return err(
157
+
ErrorType::OptionNotSupportedForTarget {
158
+
target,
159
+
option: UnsupportedOption::NativeEndianness,
160
+
},
161
+
option.location(),
162
+
);
132
163
}
133
164
134
165
Big { .. } | Little { .. } | Native { .. } => {
···
337
368
338
369
#[derive(Debug, PartialEq, Eq, Clone)]
339
370
pub enum ErrorType {
340
-
ConflictingEndiannessOptions { existing_endianness: EcoString },
341
-
ConflictingSignednessOptions { existing_signed: EcoString },
371
+
ConflictingEndiannessOptions {
372
+
existing_endianness: EcoString,
373
+
},
374
+
ConflictingSignednessOptions {
375
+
existing_signed: EcoString,
376
+
},
342
377
ConflictingSizeOptions,
343
-
ConflictingTypeOptions { existing_type: EcoString },
378
+
ConflictingTypeOptions {
379
+
existing_type: EcoString,
380
+
},
344
381
ConflictingUnitOptions,
345
382
FloatWithSize,
346
383
InvalidEndianness,
347
384
OptionNotAllowedInValue,
348
385
SegmentMustHaveSize,
349
-
SignednessUsedOnNonInt { type_: EcoString },
350
-
TypeDoesNotAllowSize { type_: EcoString },
351
-
TypeDoesNotAllowUnit { type_: EcoString },
386
+
SignednessUsedOnNonInt {
387
+
type_: EcoString,
388
+
},
389
+
TypeDoesNotAllowSize {
390
+
type_: EcoString,
391
+
},
392
+
TypeDoesNotAllowUnit {
393
+
type_: EcoString,
394
+
},
352
395
UnitMustHaveSize,
353
396
VariableUtfSegmentInPattern,
354
397
ConstantSizeNotPositive,
398
+
OptionNotSupportedForTarget {
399
+
target: Target,
400
+
option: UnsupportedOption,
401
+
},
402
+
}
403
+
404
+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
405
+
pub enum UnsupportedOption {
406
+
UtfCodepointPattern,
407
+
NativeEndianness,
355
408
}
+19
compiler-core/src/error.rs
+19
compiler-core/src/error.rs
···
1
1
#![allow(clippy::unwrap_used, clippy::expect_used)]
2
+
use crate::bit_array::UnsupportedOption;
2
3
use crate::build::{Origin, Outcome, Runtime, Target};
3
4
use crate::dependency::{PackageFetcher, ResolutionError};
4
5
use crate::diagnostic::{Diagnostic, ExtraLabel, Label, Location};
···
3017
3018
bit_array::ErrorType::ConstantSizeNotPositive => {
3018
3019
("A constant size must be a positive number", vec![])
3019
3020
}
3021
+
bit_array::ErrorType::OptionNotSupportedForTarget {
3022
+
target,
3023
+
option: UnsupportedOption::NativeEndianness,
3024
+
} => (
3025
+
"Unsupported endianness",
3026
+
vec![
3027
+
wrap_format!("The {target} target does not support the `native` endianness option.")
3028
+
],
3029
+
),
3030
+
bit_array::ErrorType::OptionNotSupportedForTarget {
3031
+
target,
3032
+
option: UnsupportedOption::UtfCodepointPattern,
3033
+
} => (
3034
+
"UTF-codepoint pattern matching is not supported",
3035
+
vec![
3036
+
wrap_format!("The {target} target does not support UTF-codepoint pattern matching.")
3037
+
],
3038
+
),
3020
3039
};
3021
3040
extra.push("See: https://tour.gleam.run/data-types/bit-arrays/".into());
3022
3041
let text = extra.join("\n");
-14
compiler-core/src/javascript/expression.rs
-14
compiler-core/src/javascript/expression.rs
···
395
395
this.wrap_expression(&segment.value)
396
396
})?;
397
397
398
-
if segment.has_native_option() {
399
-
return Err(Error::Unsupported {
400
-
feature: "This bit array segment option".into(),
401
-
location: segment.location,
402
-
});
403
-
}
404
-
405
398
match segment.options.as_slice() {
406
399
// Int segment
407
400
_ if segment.type_.is_int() => {
···
1826
1819
self.tracker.bit_array_literal_used = true;
1827
1820
let segments_array = array(segments.iter().map(|segment| {
1828
1821
let value = self.constant_expression(Context::Constant, &segment.value)?;
1829
-
1830
-
if segment.has_native_option() {
1831
-
return Err(Error::Unsupported {
1832
-
feature: "This bit array segment option".into(),
1833
-
location: segment.location,
1834
-
});
1835
-
}
1836
1822
1837
1823
match segment.options.as_slice() {
1838
1824
// Int segment
+4
-4
compiler-core/src/type_/expression.rs
+4
-4
compiler-core/src/type_/expression.rs
···
1518
1518
1519
1519
let options: Vec<_> = options.into_iter().map(infer_option).try_collect()?;
1520
1520
1521
-
let type_ = bit_array::type_options_for_value(&options).map_err(|error| {
1522
-
Error::BitArraySegmentError {
1521
+
let type_ = bit_array::type_options_for_value(&options, self.environment.target).map_err(
1522
+
|error| Error::BitArraySegmentError {
1523
1523
error: error.error,
1524
1524
location: error.location,
1525
-
}
1526
-
})?;
1525
+
},
1526
+
)?;
1527
1527
1528
1528
// Track usage of the unaligned bit arrays feature on JavaScript so that
1529
1529
// warnings can be emitted if the Gleam version constraint is too low
+5
-1
compiler-core/src/type_/pattern.rs
+5
-1
compiler-core/src/type_/pattern.rs
···
460
460
.try_collect()
461
461
.expect("The function always returns Ok");
462
462
463
-
let segment_type = match bit_array::type_options_for_pattern(&options, !is_last_segment) {
463
+
let segment_type = match bit_array::type_options_for_pattern(
464
+
&options,
465
+
!is_last_segment,
466
+
self.environment.target,
467
+
) {
464
468
Ok(type_) => type_,
465
469
Err(error) => {
466
470
self.error(Error::BitArraySegmentError {
+45
-1
compiler-core/src/type_/tests/errors.rs
+45
-1
compiler-core/src/type_/tests/errors.rs
···
1
1
use crate::{
2
-
assert_error, assert_internal_module_error, assert_module_error, assert_module_syntax_error,
2
+
assert_error, assert_internal_module_error, assert_js_module_error, assert_module_error,
3
+
assert_module_syntax_error,
3
4
};
4
5
5
6
#[test]
···
3224
3225
"
3225
3226
);
3226
3227
}
3228
+
#[test]
3229
+
fn native_endianness_javascript_target() {
3230
+
assert_js_module_error!(
3231
+
"
3232
+
pub fn main() {
3233
+
let assert <<a:native>> = <<10>>
3234
+
}
3235
+
"
3236
+
);
3237
+
}
3238
+
3239
+
#[test]
3240
+
fn utf8_codepoint_javascript_target() {
3241
+
assert_js_module_error!(
3242
+
"
3243
+
pub fn main() {
3244
+
let assert <<a:utf8_codepoint>> = <<10>>
3245
+
}
3246
+
"
3247
+
);
3248
+
}
3249
+
3250
+
#[test]
3251
+
fn utf16_codepoint_javascript_target() {
3252
+
assert_js_module_error!(
3253
+
"
3254
+
pub fn main() {
3255
+
let assert <<a:utf16_codepoint>> = <<10>>
3256
+
}
3257
+
"
3258
+
);
3259
+
}
3260
+
3261
+
#[test]
3262
+
fn utf32_codepoint_javascript_target() {
3263
+
assert_js_module_error!(
3264
+
"
3265
+
pub fn main() {
3266
+
let assert <<a:utf32_codepoint>> = <<10>>
3267
+
}
3268
+
"
3269
+
);
3270
+
}
+20
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__native_endianness_javascript_target.snap
+20
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__native_endianness_javascript_target.snap
···
1
+
---
2
+
source: compiler-core/src/type_/tests/errors.rs
3
+
expression: "\npub fn main() {\n let assert <<a:native>> = <<10>>\n}\n"
4
+
---
5
+
----- SOURCE CODE
6
+
7
+
pub fn main() {
8
+
let assert <<a:native>> = <<10>>
9
+
}
10
+
11
+
12
+
----- ERROR
13
+
error: Invalid bit array segment
14
+
┌─ /src/one/two.gleam:3:18
15
+
│
16
+
3 │ let assert <<a:native>> = <<10>>
17
+
│ ^^^^^^ Unsupported endianness
18
+
19
+
The javascript target does not support the `native` endianness option.
20
+
See: https://tour.gleam.run/data-types/bit-arrays/
+20
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__utf16_codepoint_javascript_target.snap
+20
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__utf16_codepoint_javascript_target.snap
···
1
+
---
2
+
source: compiler-core/src/type_/tests/errors.rs
3
+
expression: "\npub fn main() {\n let assert <<a:utf16_codepoint>> = <<10>>\n}\n"
4
+
---
5
+
----- SOURCE CODE
6
+
7
+
pub fn main() {
8
+
let assert <<a:utf16_codepoint>> = <<10>>
9
+
}
10
+
11
+
12
+
----- ERROR
13
+
error: Invalid bit array segment
14
+
┌─ /src/one/two.gleam:3:18
15
+
│
16
+
3 │ let assert <<a:utf16_codepoint>> = <<10>>
17
+
│ ^^^^^^^^^^^^^^^ UTF-codepoint pattern matching is not supported
18
+
19
+
The javascript target does not support UTF-codepoint pattern matching.
20
+
See: https://tour.gleam.run/data-types/bit-arrays/
+20
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__utf32_codepoint_javascript_target.snap
+20
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__utf32_codepoint_javascript_target.snap
···
1
+
---
2
+
source: compiler-core/src/type_/tests/errors.rs
3
+
expression: "\npub fn main() {\n let assert <<a:utf32_codepoint>> = <<10>>\n}\n"
4
+
---
5
+
----- SOURCE CODE
6
+
7
+
pub fn main() {
8
+
let assert <<a:utf32_codepoint>> = <<10>>
9
+
}
10
+
11
+
12
+
----- ERROR
13
+
error: Invalid bit array segment
14
+
┌─ /src/one/two.gleam:3:18
15
+
│
16
+
3 │ let assert <<a:utf32_codepoint>> = <<10>>
17
+
│ ^^^^^^^^^^^^^^^ UTF-codepoint pattern matching is not supported
18
+
19
+
The javascript target does not support UTF-codepoint pattern matching.
20
+
See: https://tour.gleam.run/data-types/bit-arrays/
+20
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__utf8_codepoint_javascript_target.snap
+20
compiler-core/src/type_/tests/snapshots/gleam_core__type___tests__errors__utf8_codepoint_javascript_target.snap
···
1
+
---
2
+
source: compiler-core/src/type_/tests/errors.rs
3
+
expression: "\npub fn main() {\n let assert <<a:utf8_codepoint>> = <<10>>\n}\n"
4
+
---
5
+
----- SOURCE CODE
6
+
7
+
pub fn main() {
8
+
let assert <<a:utf8_codepoint>> = <<10>>
9
+
}
10
+
11
+
12
+
----- ERROR
13
+
error: Invalid bit array segment
14
+
┌─ /src/one/two.gleam:3:18
15
+
│
16
+
3 │ let assert <<a:utf8_codepoint>> = <<10>>
17
+
│ ^^^^^^^^^^^^^^ UTF-codepoint pattern matching is not supported
18
+
19
+
The javascript target does not support UTF-codepoint pattern matching.
20
+
See: https://tour.gleam.run/data-types/bit-arrays/