Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

fix error with unreachable binary patterns

author
Giacomo Cavalieri
committer
Louis Pilfold
date (Jan 13, 2026, 9:00 PM UTC) commit 0fc12bbf parent 8ca2875c change-id wvrwnlws
+89 -1196
+11 -5
CHANGELOG.md
··· 4 4 5 5 ### Compiler 6 6 7 - - The compiler now reports an error when integer and float binary operators are used 8 - incorrectly in case expression guards. ([Adi Salimgereyev](https://github.com/abs0luty)) 7 + - The compiler now reports an error when integer and float binary operators are 8 + used incorrectly in case expression guards. 9 + ([Adi Salimgereyev](https://github.com/abs0luty)) 9 10 10 11 - The compiler now supports string concatenation in clause guards: 11 12 12 13 ```gleam 13 14 case message { 14 - #(version, action) if version <> ":" <> action == "v1:delete" -> handle_delete() 15 + #(version, action) if version <> ":" <> action == "v1:delete" -> 16 + handle_delete() 15 17 _ -> ignore() 16 18 } 17 19 ``` ··· 34 36 35 37 ### Bug fixes 36 38 39 + - Fixed a bug where some bit array patterns would erroneously be marked as 40 + unreachable. 41 + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 42 + 37 43 - The compiler now correctly tracks the minimum required version for constant 38 44 record updates to be `>= 1.14.0`. 39 45 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) ··· 56 62 - Fixed a bug that would result in not being able to rename an aliased pattern. 57 63 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 58 64 59 - - Added an error message when attempting to update packages that are not dependencies 60 - of the project, instead of failing silently. 65 + - Added an error message when attempting to update packages that are not 66 + dependencies of the project, instead of failing silently. 61 67 ([Etienne Boutet](https://github.com/EtienneBoutet), 62 68 [Vladislav Shakitskiy](https://github.com/vshakitskiy)) 63 69
+15 -2
compiler-core/src/exhaustiveness.rs
··· 1074 1074 pub read_action: ReadAction, 1075 1075 } 1076 1076 1077 + #[derive(Debug)] 1077 1078 struct Interference { 1078 1079 interfering_bits_are_equal: bool, 1079 1080 first_encloses_second: bool, ··· 1223 1224 let bits_one = self.value.constant_bits()?; 1224 1225 let bits_other = other.value.constant_bits()?; 1225 1226 let end = (offset_other + size_other).min(offset_one + size_one); 1227 + 1228 + let range_one = offset_one..=(offset_one + size_one); 1229 + let range_other = offset_other..=(offset_other + size_other); 1230 + 1226 1231 Some(Interference { 1227 1232 interfering_bits_are_equal: bits_one[offset_other - offset_one..end - offset_one] 1228 1233 == bits_other[0..end - offset_other], 1229 - first_encloses_second: size_one + offset_one >= size_other + offset_other, 1230 - second_encloses_first: size_other + offset_other >= size_one + offset_one, 1234 + first_encloses_second: range_contains(&range_one, &range_other), 1235 + second_encloses_first: range_contains(&range_other, &range_one), 1231 1236 }) 1232 1237 } 1238 + } 1239 + 1240 + /// Returns true if the first range fully contains the other one. 1241 + fn range_contains( 1242 + one: &std::ops::RangeInclusive<usize>, 1243 + other: &std::ops::RangeInclusive<usize>, 1244 + ) -> bool { 1245 + one.contains(other.start()) && one.contains(other.end()) 1233 1246 } 1234 1247 1235 1248 /// A value that can be matched in a bit array pattern's segment. We do not use
+16
compiler-core/src/javascript/tests/bit_arrays.rs
··· 2659 2659 "# 2660 2660 ); 2661 2661 } 2662 + 2663 + #[test] 2664 + fn bit_array_pattern_match_all_reachable() { 2665 + assert_js!( 2666 + r#" 2667 + pub fn main(x) { 2668 + case x { 2669 + <<_, "==">> -> 1 2670 + <<_, _, "=">> -> 2 2671 + // ^^^ This should be reachable 2672 + _ -> 3 2673 + } 2674 + } 2675 + "# 2676 + ) 2677 + }
-32
compiler-core/src/javascript/tests/case.rs
··· 843 843 } 844 844 845 845 #[test] 846 - fn interfering_string_pattern_fails_if_succeeding() { 847 - assert_js!( 848 - r#" 849 - pub fn wibble(bits) { 850 - case bits { 851 - <<"aaa", 0, _:bits>> -> 1 852 - // If the first one fails, we know this one won't match, so it won't appear 853 - // in the final else branch! 854 - <<_, "aa", 1, _:bits>> -> 2 855 - _ -> 3 856 - } 857 - }"# 858 - ); 859 - } 860 - 861 - #[test] 862 846 fn interfering_string_pattern_succeeds_if_succeeding() { 863 847 assert_js!( 864 848 r#" ··· 868 852 // If the first one succeeds, so will the second check, so it won't be 869 853 // performed twice inside the first if branch! 870 854 <<"aaa", 1, _:bits>> -> 2 871 - _ -> 3 872 - } 873 - }"# 874 - ); 875 - } 876 - 877 - #[test] 878 - fn interfering_string_pattern_fails_if_failing() { 879 - assert_js!( 880 - r#" 881 - pub fn wibble(bits) { 882 - case bits { 883 - <<"aaaa", 0, _:bits>> -> 1 884 - // If the first one fails we know this one will fail as well, so it won't 885 - // appear in the final else branch. 886 - <<_, "aaabbb", 1, _:bits>> -> 2 887 855 _ -> 3 888 856 } 889 857 }"#
+30
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__bit_arrays__bit_array_pattern_match_all_reachable.snap
··· 1 + --- 2 + source: compiler-core/src/javascript/tests/bit_arrays.rs 3 + expression: "\npub fn main(x) {\n case x {\n <<_, \"==\">> -> 1\n <<_, _, \"=\">> -> 2\n // ^^^ This should be reachable\n _ -> 3\n }\n}\n " 4 + --- 5 + ----- SOURCE CODE 6 + 7 + pub fn main(x) { 8 + case x { 9 + <<_, "==">> -> 1 10 + <<_, _, "=">> -> 2 11 + // ^^^ This should be reachable 12 + _ -> 3 13 + } 14 + } 15 + 16 + 17 + ----- COMPILED JAVASCRIPT 18 + export function main(x) { 19 + if (x.bitSize >= 8 && x.bitSize === 24) { 20 + if (x.byteAt(1) === 61 && x.byteAt(2) === 61) { 21 + return 1; 22 + } else if (x.byteAt(2) === 61) { 23 + return 2; 24 + } else { 25 + return 3; 26 + } 27 + } else { 28 + return 3; 29 + } 30 + }
-47
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__case__interfering_string_pattern_fails_if_failing.snap
··· 1 - --- 2 - source: compiler-core/src/javascript/tests/case.rs 3 - expression: "\npub fn wibble(bits) {\n case bits {\n <<\"aaaa\", 0, _:bits>> -> 1\n // If the first one fails we know this one will fail as well, so it won't\n // appear in the final else branch.\n <<_, \"aaabbb\", 1, _:bits>> -> 2\n _ -> 3\n }\n}" 4 - --- 5 - ----- SOURCE CODE 6 - 7 - pub fn wibble(bits) { 8 - case bits { 9 - <<"aaaa", 0, _:bits>> -> 1 10 - // If the first one fails we know this one will fail as well, so it won't 11 - // appear in the final else branch. 12 - <<_, "aaabbb", 1, _:bits>> -> 2 13 - _ -> 3 14 - } 15 - } 16 - 17 - ----- COMPILED JAVASCRIPT 18 - export function wibble(bits) { 19 - if ( 20 - bits.bitSize >= 32 && 21 - bits.byteAt(0) === 97 && 22 - bits.byteAt(1) === 97 && 23 - bits.byteAt(2) === 97 && 24 - bits.byteAt(3) === 97 && 25 - bits.bitSize >= 40 26 - ) { 27 - if (bits.byteAt(4) === 0) { 28 - return 1; 29 - } else if ( 30 - bits.bitSize >= 56 && 31 - bits.byteAt(1) === 97 && 32 - bits.byteAt(2) === 97 && 33 - bits.byteAt(3) === 97 && 34 - bits.byteAt(4) === 98 && 35 - bits.byteAt(5) === 98 && 36 - bits.byteAt(6) === 98 && 37 - bits.bitSize >= 64 && 38 - bits.byteAt(7) === 1 39 - ) { 40 - return 2; 41 - } else { 42 - return 3; 43 - } 44 - } else { 45 - return 3; 46 - } 47 - }
-34
compiler-core/src/javascript/tests/snapshots/gleam_core__javascript__tests__case__interfering_string_pattern_fails_if_succeeding.snap
··· 1 - --- 2 - source: compiler-core/src/javascript/tests/case.rs 3 - expression: "\npub fn wibble(bits) {\n case bits {\n <<\"aaa\", 0, _:bits>> -> 1\n // If the first one fails, we know this one won't match, so it won't appear\n // in the final else branch!\n <<_, \"aa\", 1, _:bits>> -> 2\n _ -> 3\n }\n}" 4 - --- 5 - ----- SOURCE CODE 6 - 7 - pub fn wibble(bits) { 8 - case bits { 9 - <<"aaa", 0, _:bits>> -> 1 10 - // If the first one fails, we know this one won't match, so it won't appear 11 - // in the final else branch! 12 - <<_, "aa", 1, _:bits>> -> 2 13 - _ -> 3 14 - } 15 - } 16 - 17 - ----- COMPILED JAVASCRIPT 18 - export function wibble(bits) { 19 - if ( 20 - bits.bitSize >= 24 && 21 - bits.byteAt(0) === 97 && bits.byteAt(1) === 97 && bits.byteAt(2) === 97 && 22 - bits.bitSize >= 32 23 - ) { 24 - if (bits.byteAt(3) === 0) { 25 - return 1; 26 - } else if (bits.byteAt(3) === 1) { 27 - return 2; 28 - } else { 29 - return 3; 30 - } 31 - } else { 32 - return 3; 33 - } 34 - }
-366
compiler-core/src/parse/snapshots/gleam_core__parse__tests__const_record_spread_all_fields.snap
··· 1 - --- 2 - source: compiler-core/src/parse/tests.rs 3 - expression: "\ntype Person {\n Person(name: String, age: Int, city: String)\n}\n\nconst base = Person(\"Alice\", 30, \"London\")\nconst updated = Person(..base, name: \"Bob\", age: 25, city: \"Paris\")\n" 4 - --- 5 - Parsed { 6 - module: Module { 7 - name: "", 8 - documentation: [], 9 - type_info: (), 10 - definitions: [ 11 - TargetedDefinition { 12 - definition: CustomType( 13 - CustomType { 14 - location: SrcSpan { 15 - start: 1, 16 - end: 12, 17 - }, 18 - end_position: 63, 19 - name: "Person", 20 - name_location: SrcSpan { 21 - start: 6, 22 - end: 12, 23 - }, 24 - publicity: Private, 25 - constructors: [ 26 - RecordConstructor { 27 - location: SrcSpan { 28 - start: 17, 29 - end: 61, 30 - }, 31 - name_location: SrcSpan { 32 - start: 17, 33 - end: 23, 34 - }, 35 - name: "Person", 36 - arguments: [ 37 - RecordConstructorArg { 38 - label: Some( 39 - ( 40 - SrcSpan { 41 - start: 24, 42 - end: 28, 43 - }, 44 - "name", 45 - ), 46 - ), 47 - ast: Constructor( 48 - TypeAstConstructor { 49 - location: SrcSpan { 50 - start: 30, 51 - end: 36, 52 - }, 53 - name_location: SrcSpan { 54 - start: 30, 55 - end: 36, 56 - }, 57 - module: None, 58 - name: "String", 59 - arguments: [], 60 - start_parentheses: None, 61 - }, 62 - ), 63 - location: SrcSpan { 64 - start: 24, 65 - end: 36, 66 - }, 67 - type_: (), 68 - doc: None, 69 - }, 70 - RecordConstructorArg { 71 - label: Some( 72 - ( 73 - SrcSpan { 74 - start: 38, 75 - end: 41, 76 - }, 77 - "age", 78 - ), 79 - ), 80 - ast: Constructor( 81 - TypeAstConstructor { 82 - location: SrcSpan { 83 - start: 43, 84 - end: 46, 85 - }, 86 - name_location: SrcSpan { 87 - start: 43, 88 - end: 46, 89 - }, 90 - module: None, 91 - name: "Int", 92 - arguments: [], 93 - start_parentheses: None, 94 - }, 95 - ), 96 - location: SrcSpan { 97 - start: 38, 98 - end: 46, 99 - }, 100 - type_: (), 101 - doc: None, 102 - }, 103 - RecordConstructorArg { 104 - label: Some( 105 - ( 106 - SrcSpan { 107 - start: 48, 108 - end: 52, 109 - }, 110 - "city", 111 - ), 112 - ), 113 - ast: Constructor( 114 - TypeAstConstructor { 115 - location: SrcSpan { 116 - start: 54, 117 - end: 60, 118 - }, 119 - name_location: SrcSpan { 120 - start: 54, 121 - end: 60, 122 - }, 123 - module: None, 124 - name: "String", 125 - arguments: [], 126 - start_parentheses: None, 127 - }, 128 - ), 129 - location: SrcSpan { 130 - start: 48, 131 - end: 60, 132 - }, 133 - type_: (), 134 - doc: None, 135 - }, 136 - ], 137 - documentation: None, 138 - deprecation: NotDeprecated, 139 - }, 140 - ], 141 - documentation: None, 142 - deprecation: NotDeprecated, 143 - opaque: false, 144 - parameters: [], 145 - typed_parameters: [], 146 - external_erlang: None, 147 - external_javascript: None, 148 - }, 149 - ), 150 - target: None, 151 - }, 152 - TargetedDefinition { 153 - definition: ModuleConstant( 154 - ModuleConstant { 155 - documentation: None, 156 - location: SrcSpan { 157 - start: 65, 158 - end: 75, 159 - }, 160 - publicity: Private, 161 - name: "base", 162 - name_location: SrcSpan { 163 - start: 71, 164 - end: 75, 165 - }, 166 - annotation: None, 167 - value: Record { 168 - location: SrcSpan { 169 - start: 78, 170 - end: 107, 171 - }, 172 - module: None, 173 - name: "Person", 174 - arguments: [ 175 - CallArg { 176 - label: None, 177 - location: SrcSpan { 178 - start: 85, 179 - end: 92, 180 - }, 181 - value: String { 182 - location: SrcSpan { 183 - start: 85, 184 - end: 92, 185 - }, 186 - value: "Alice", 187 - }, 188 - implicit: None, 189 - }, 190 - CallArg { 191 - label: None, 192 - location: SrcSpan { 193 - start: 94, 194 - end: 96, 195 - }, 196 - value: Int { 197 - location: SrcSpan { 198 - start: 94, 199 - end: 96, 200 - }, 201 - value: "30", 202 - int_value: 30, 203 - }, 204 - implicit: None, 205 - }, 206 - CallArg { 207 - label: None, 208 - location: SrcSpan { 209 - start: 98, 210 - end: 106, 211 - }, 212 - value: String { 213 - location: SrcSpan { 214 - start: 98, 215 - end: 106, 216 - }, 217 - value: "London", 218 - }, 219 - implicit: None, 220 - }, 221 - ], 222 - tag: (), 223 - type_: (), 224 - field_map: Unknown, 225 - record_constructor: None, 226 - }, 227 - type_: (), 228 - deprecation: NotDeprecated, 229 - implementations: Implementations { 230 - gleam: true, 231 - can_run_on_erlang: true, 232 - can_run_on_javascript: true, 233 - uses_erlang_externals: false, 234 - uses_javascript_externals: false, 235 - }, 236 - }, 237 - ), 238 - target: None, 239 - }, 240 - TargetedDefinition { 241 - definition: ModuleConstant( 242 - ModuleConstant { 243 - documentation: None, 244 - location: SrcSpan { 245 - start: 108, 246 - end: 121, 247 - }, 248 - publicity: Private, 249 - name: "updated", 250 - name_location: SrcSpan { 251 - start: 114, 252 - end: 121, 253 - }, 254 - annotation: None, 255 - value: RecordUpdate { 256 - location: SrcSpan { 257 - start: 124, 258 - end: 175, 259 - }, 260 - constructor_location: SrcSpan { 261 - start: 124, 262 - end: 130, 263 - }, 264 - module: None, 265 - name: "Person", 266 - record: Var { 267 - location: SrcSpan { 268 - start: 133, 269 - end: 137, 270 - }, 271 - module: None, 272 - name: "base", 273 - constructor: None, 274 - type_: (), 275 - }, 276 - arguments: [ 277 - RecordUpdateArg { 278 - label: "name", 279 - location: SrcSpan { 280 - start: 139, 281 - end: 150, 282 - }, 283 - value: String { 284 - location: SrcSpan { 285 - start: 145, 286 - end: 150, 287 - }, 288 - value: "Bob", 289 - }, 290 - }, 291 - RecordUpdateArg { 292 - label: "age", 293 - location: SrcSpan { 294 - start: 152, 295 - end: 159, 296 - }, 297 - value: Int { 298 - location: SrcSpan { 299 - start: 157, 300 - end: 159, 301 - }, 302 - value: "25", 303 - int_value: 25, 304 - }, 305 - }, 306 - RecordUpdateArg { 307 - label: "city", 308 - location: SrcSpan { 309 - start: 161, 310 - end: 174, 311 - }, 312 - value: String { 313 - location: SrcSpan { 314 - start: 167, 315 - end: 174, 316 - }, 317 - value: "Paris", 318 - }, 319 - }, 320 - ], 321 - tag: (), 322 - type_: (), 323 - field_map: Unknown, 324 - }, 325 - type_: (), 326 - deprecation: NotDeprecated, 327 - implementations: Implementations { 328 - gleam: true, 329 - can_run_on_erlang: true, 330 - can_run_on_javascript: true, 331 - uses_erlang_externals: false, 332 - uses_javascript_externals: false, 333 - }, 334 - }, 335 - ), 336 - target: None, 337 - }, 338 - ], 339 - names: Names { 340 - local_types: {}, 341 - imported_modules: {}, 342 - type_variables: {}, 343 - local_value_constructors: {}, 344 - reexport_aliases: {}, 345 - }, 346 - unused_definition_positions: {}, 347 - }, 348 - extra: ModuleExtra { 349 - module_comments: [], 350 - doc_comments: [], 351 - comments: [], 352 - empty_lines: [ 353 - 64, 354 - ], 355 - new_lines: [ 356 - 0, 357 - 14, 358 - 61, 359 - 63, 360 - 64, 361 - 107, 362 - 175, 363 - ], 364 - trailing_commas: [], 365 - }, 366 - }
-289
compiler-core/src/parse/snapshots/gleam_core__parse__tests__const_record_spread_basic.snap
··· 1 - --- 2 - source: compiler-core/src/parse/tests.rs 3 - expression: "\ntype Person {\n Person(name: String, age: Int)\n}\n\nconst alice = Person(\"Alice\", 30)\nconst bob = Person(..alice, name: \"Bob\")\n" 4 - --- 5 - Parsed { 6 - module: Module { 7 - name: "", 8 - documentation: [], 9 - type_info: (), 10 - definitions: [ 11 - TargetedDefinition { 12 - definition: CustomType( 13 - CustomType { 14 - location: SrcSpan { 15 - start: 1, 16 - end: 12, 17 - }, 18 - end_position: 49, 19 - name: "Person", 20 - name_location: SrcSpan { 21 - start: 6, 22 - end: 12, 23 - }, 24 - publicity: Private, 25 - constructors: [ 26 - RecordConstructor { 27 - location: SrcSpan { 28 - start: 17, 29 - end: 47, 30 - }, 31 - name_location: SrcSpan { 32 - start: 17, 33 - end: 23, 34 - }, 35 - name: "Person", 36 - arguments: [ 37 - RecordConstructorArg { 38 - label: Some( 39 - ( 40 - SrcSpan { 41 - start: 24, 42 - end: 28, 43 - }, 44 - "name", 45 - ), 46 - ), 47 - ast: Constructor( 48 - TypeAstConstructor { 49 - location: SrcSpan { 50 - start: 30, 51 - end: 36, 52 - }, 53 - name_location: SrcSpan { 54 - start: 30, 55 - end: 36, 56 - }, 57 - module: None, 58 - name: "String", 59 - arguments: [], 60 - start_parentheses: None, 61 - }, 62 - ), 63 - location: SrcSpan { 64 - start: 24, 65 - end: 36, 66 - }, 67 - type_: (), 68 - doc: None, 69 - }, 70 - RecordConstructorArg { 71 - label: Some( 72 - ( 73 - SrcSpan { 74 - start: 38, 75 - end: 41, 76 - }, 77 - "age", 78 - ), 79 - ), 80 - ast: Constructor( 81 - TypeAstConstructor { 82 - location: SrcSpan { 83 - start: 43, 84 - end: 46, 85 - }, 86 - name_location: SrcSpan { 87 - start: 43, 88 - end: 46, 89 - }, 90 - module: None, 91 - name: "Int", 92 - arguments: [], 93 - start_parentheses: None, 94 - }, 95 - ), 96 - location: SrcSpan { 97 - start: 38, 98 - end: 46, 99 - }, 100 - type_: (), 101 - doc: None, 102 - }, 103 - ], 104 - documentation: None, 105 - deprecation: NotDeprecated, 106 - }, 107 - ], 108 - documentation: None, 109 - deprecation: NotDeprecated, 110 - opaque: false, 111 - parameters: [], 112 - typed_parameters: [], 113 - external_erlang: None, 114 - external_javascript: None, 115 - }, 116 - ), 117 - target: None, 118 - }, 119 - TargetedDefinition { 120 - definition: ModuleConstant( 121 - ModuleConstant { 122 - documentation: None, 123 - location: SrcSpan { 124 - start: 51, 125 - end: 62, 126 - }, 127 - publicity: Private, 128 - name: "alice", 129 - name_location: SrcSpan { 130 - start: 57, 131 - end: 62, 132 - }, 133 - annotation: None, 134 - value: Record { 135 - location: SrcSpan { 136 - start: 65, 137 - end: 84, 138 - }, 139 - module: None, 140 - name: "Person", 141 - arguments: [ 142 - CallArg { 143 - label: None, 144 - location: SrcSpan { 145 - start: 72, 146 - end: 79, 147 - }, 148 - value: String { 149 - location: SrcSpan { 150 - start: 72, 151 - end: 79, 152 - }, 153 - value: "Alice", 154 - }, 155 - implicit: None, 156 - }, 157 - CallArg { 158 - label: None, 159 - location: SrcSpan { 160 - start: 81, 161 - end: 83, 162 - }, 163 - value: Int { 164 - location: SrcSpan { 165 - start: 81, 166 - end: 83, 167 - }, 168 - value: "30", 169 - int_value: 30, 170 - }, 171 - implicit: None, 172 - }, 173 - ], 174 - tag: (), 175 - type_: (), 176 - field_map: Unknown, 177 - record_constructor: None, 178 - }, 179 - type_: (), 180 - deprecation: NotDeprecated, 181 - implementations: Implementations { 182 - gleam: true, 183 - can_run_on_erlang: true, 184 - can_run_on_javascript: true, 185 - uses_erlang_externals: false, 186 - uses_javascript_externals: false, 187 - }, 188 - }, 189 - ), 190 - target: None, 191 - }, 192 - TargetedDefinition { 193 - definition: ModuleConstant( 194 - ModuleConstant { 195 - documentation: None, 196 - location: SrcSpan { 197 - start: 85, 198 - end: 94, 199 - }, 200 - publicity: Private, 201 - name: "bob", 202 - name_location: SrcSpan { 203 - start: 91, 204 - end: 94, 205 - }, 206 - annotation: None, 207 - value: RecordUpdate { 208 - location: SrcSpan { 209 - start: 97, 210 - end: 125, 211 - }, 212 - constructor_location: SrcSpan { 213 - start: 97, 214 - end: 103, 215 - }, 216 - module: None, 217 - name: "Person", 218 - record: Var { 219 - location: SrcSpan { 220 - start: 106, 221 - end: 111, 222 - }, 223 - module: None, 224 - name: "alice", 225 - constructor: None, 226 - type_: (), 227 - }, 228 - arguments: [ 229 - RecordUpdateArg { 230 - label: "name", 231 - location: SrcSpan { 232 - start: 113, 233 - end: 124, 234 - }, 235 - value: String { 236 - location: SrcSpan { 237 - start: 119, 238 - end: 124, 239 - }, 240 - value: "Bob", 241 - }, 242 - }, 243 - ], 244 - tag: (), 245 - type_: (), 246 - field_map: Unknown, 247 - }, 248 - type_: (), 249 - deprecation: NotDeprecated, 250 - implementations: Implementations { 251 - gleam: true, 252 - can_run_on_erlang: true, 253 - can_run_on_javascript: true, 254 - uses_erlang_externals: false, 255 - uses_javascript_externals: false, 256 - }, 257 - }, 258 - ), 259 - target: None, 260 - }, 261 - ], 262 - names: Names { 263 - local_types: {}, 264 - imported_modules: {}, 265 - type_variables: {}, 266 - local_value_constructors: {}, 267 - reexport_aliases: {}, 268 - }, 269 - unused_definition_positions: {}, 270 - }, 271 - extra: ModuleExtra { 272 - module_comments: [], 273 - doc_comments: [], 274 - comments: [], 275 - empty_lines: [ 276 - 50, 277 - ], 278 - new_lines: [ 279 - 0, 280 - 14, 281 - 47, 282 - 49, 283 - 50, 284 - 84, 285 - 125, 286 - ], 287 - trailing_commas: [], 288 - }, 289 - }
-274
compiler-core/src/parse/snapshots/gleam_core__parse__tests__const_record_spread_only.snap
··· 1 - --- 2 - source: compiler-core/src/parse/tests.rs 3 - expression: "\ntype Person {\n Person(name: String, age: Int)\n}\n\nconst alice = Person(\"Alice\", 30)\nconst bob = Person(..alice)\n" 4 - --- 5 - Parsed { 6 - module: Module { 7 - name: "", 8 - documentation: [], 9 - type_info: (), 10 - definitions: [ 11 - TargetedDefinition { 12 - definition: CustomType( 13 - CustomType { 14 - location: SrcSpan { 15 - start: 1, 16 - end: 12, 17 - }, 18 - end_position: 49, 19 - name: "Person", 20 - name_location: SrcSpan { 21 - start: 6, 22 - end: 12, 23 - }, 24 - publicity: Private, 25 - constructors: [ 26 - RecordConstructor { 27 - location: SrcSpan { 28 - start: 17, 29 - end: 47, 30 - }, 31 - name_location: SrcSpan { 32 - start: 17, 33 - end: 23, 34 - }, 35 - name: "Person", 36 - arguments: [ 37 - RecordConstructorArg { 38 - label: Some( 39 - ( 40 - SrcSpan { 41 - start: 24, 42 - end: 28, 43 - }, 44 - "name", 45 - ), 46 - ), 47 - ast: Constructor( 48 - TypeAstConstructor { 49 - location: SrcSpan { 50 - start: 30, 51 - end: 36, 52 - }, 53 - name_location: SrcSpan { 54 - start: 30, 55 - end: 36, 56 - }, 57 - module: None, 58 - name: "String", 59 - arguments: [], 60 - start_parentheses: None, 61 - }, 62 - ), 63 - location: SrcSpan { 64 - start: 24, 65 - end: 36, 66 - }, 67 - type_: (), 68 - doc: None, 69 - }, 70 - RecordConstructorArg { 71 - label: Some( 72 - ( 73 - SrcSpan { 74 - start: 38, 75 - end: 41, 76 - }, 77 - "age", 78 - ), 79 - ), 80 - ast: Constructor( 81 - TypeAstConstructor { 82 - location: SrcSpan { 83 - start: 43, 84 - end: 46, 85 - }, 86 - name_location: SrcSpan { 87 - start: 43, 88 - end: 46, 89 - }, 90 - module: None, 91 - name: "Int", 92 - arguments: [], 93 - start_parentheses: None, 94 - }, 95 - ), 96 - location: SrcSpan { 97 - start: 38, 98 - end: 46, 99 - }, 100 - type_: (), 101 - doc: None, 102 - }, 103 - ], 104 - documentation: None, 105 - deprecation: NotDeprecated, 106 - }, 107 - ], 108 - documentation: None, 109 - deprecation: NotDeprecated, 110 - opaque: false, 111 - parameters: [], 112 - typed_parameters: [], 113 - external_erlang: None, 114 - external_javascript: None, 115 - }, 116 - ), 117 - target: None, 118 - }, 119 - TargetedDefinition { 120 - definition: ModuleConstant( 121 - ModuleConstant { 122 - documentation: None, 123 - location: SrcSpan { 124 - start: 51, 125 - end: 62, 126 - }, 127 - publicity: Private, 128 - name: "alice", 129 - name_location: SrcSpan { 130 - start: 57, 131 - end: 62, 132 - }, 133 - annotation: None, 134 - value: Record { 135 - location: SrcSpan { 136 - start: 65, 137 - end: 84, 138 - }, 139 - module: None, 140 - name: "Person", 141 - arguments: [ 142 - CallArg { 143 - label: None, 144 - location: SrcSpan { 145 - start: 72, 146 - end: 79, 147 - }, 148 - value: String { 149 - location: SrcSpan { 150 - start: 72, 151 - end: 79, 152 - }, 153 - value: "Alice", 154 - }, 155 - implicit: None, 156 - }, 157 - CallArg { 158 - label: None, 159 - location: SrcSpan { 160 - start: 81, 161 - end: 83, 162 - }, 163 - value: Int { 164 - location: SrcSpan { 165 - start: 81, 166 - end: 83, 167 - }, 168 - value: "30", 169 - int_value: 30, 170 - }, 171 - implicit: None, 172 - }, 173 - ], 174 - tag: (), 175 - type_: (), 176 - field_map: Unknown, 177 - record_constructor: None, 178 - }, 179 - type_: (), 180 - deprecation: NotDeprecated, 181 - implementations: Implementations { 182 - gleam: true, 183 - can_run_on_erlang: true, 184 - can_run_on_javascript: true, 185 - uses_erlang_externals: false, 186 - uses_javascript_externals: false, 187 - }, 188 - }, 189 - ), 190 - target: None, 191 - }, 192 - TargetedDefinition { 193 - definition: ModuleConstant( 194 - ModuleConstant { 195 - documentation: None, 196 - location: SrcSpan { 197 - start: 85, 198 - end: 94, 199 - }, 200 - publicity: Private, 201 - name: "bob", 202 - name_location: SrcSpan { 203 - start: 91, 204 - end: 94, 205 - }, 206 - annotation: None, 207 - value: RecordUpdate { 208 - location: SrcSpan { 209 - start: 97, 210 - end: 112, 211 - }, 212 - constructor_location: SrcSpan { 213 - start: 97, 214 - end: 103, 215 - }, 216 - module: None, 217 - name: "Person", 218 - record: Var { 219 - location: SrcSpan { 220 - start: 106, 221 - end: 111, 222 - }, 223 - module: None, 224 - name: "alice", 225 - constructor: None, 226 - type_: (), 227 - }, 228 - arguments: [], 229 - tag: (), 230 - type_: (), 231 - field_map: Unknown, 232 - }, 233 - type_: (), 234 - deprecation: NotDeprecated, 235 - implementations: Implementations { 236 - gleam: true, 237 - can_run_on_erlang: true, 238 - can_run_on_javascript: true, 239 - uses_erlang_externals: false, 240 - uses_javascript_externals: false, 241 - }, 242 - }, 243 - ), 244 - target: None, 245 - }, 246 - ], 247 - names: Names { 248 - local_types: {}, 249 - imported_modules: {}, 250 - type_variables: {}, 251 - local_value_constructors: {}, 252 - reexport_aliases: {}, 253 - }, 254 - unused_definition_positions: {}, 255 - }, 256 - extra: ModuleExtra { 257 - module_comments: [], 258 - doc_comments: [], 259 - comments: [], 260 - empty_lines: [ 261 - 50, 262 - ], 263 - new_lines: [ 264 - 0, 265 - 14, 266 - 47, 267 - 49, 268 - 50, 269 - 84, 270 - 112, 271 - ], 272 - trailing_commas: [], 273 - }, 274 - }
-120
compiler-core/src/parse/snapshots/gleam_core__parse__tests__const_record_spread_with_module.snap
··· 1 - --- 2 - source: compiler-core/src/parse/tests.rs 3 - expression: "\nconst local_const = other.Record(..other.base, field: value)\n" 4 - --- 5 - Parsed { 6 - module: Module { 7 - name: "", 8 - documentation: [], 9 - type_info: (), 10 - definitions: [ 11 - TargetedDefinition { 12 - definition: ModuleConstant( 13 - ModuleConstant { 14 - documentation: None, 15 - location: SrcSpan { 16 - start: 1, 17 - end: 18, 18 - }, 19 - publicity: Private, 20 - name: "local_const", 21 - name_location: SrcSpan { 22 - start: 7, 23 - end: 18, 24 - }, 25 - annotation: None, 26 - value: RecordUpdate { 27 - location: SrcSpan { 28 - start: 21, 29 - end: 61, 30 - }, 31 - constructor_location: SrcSpan { 32 - start: 21, 33 - end: 33, 34 - }, 35 - module: Some( 36 - ( 37 - "other", 38 - SrcSpan { 39 - start: 21, 40 - end: 26, 41 - }, 42 - ), 43 - ), 44 - name: "Record", 45 - record: Var { 46 - location: SrcSpan { 47 - start: 36, 48 - end: 46, 49 - }, 50 - module: Some( 51 - ( 52 - "other", 53 - SrcSpan { 54 - start: 36, 55 - end: 41, 56 - }, 57 - ), 58 - ), 59 - name: "base", 60 - constructor: None, 61 - type_: (), 62 - }, 63 - arguments: [ 64 - RecordUpdateArg { 65 - label: "field", 66 - location: SrcSpan { 67 - start: 48, 68 - end: 60, 69 - }, 70 - value: Var { 71 - location: SrcSpan { 72 - start: 55, 73 - end: 60, 74 - }, 75 - module: None, 76 - name: "value", 77 - constructor: None, 78 - type_: (), 79 - }, 80 - }, 81 - ], 82 - tag: (), 83 - type_: (), 84 - field_map: Unknown, 85 - }, 86 - type_: (), 87 - deprecation: NotDeprecated, 88 - implementations: Implementations { 89 - gleam: true, 90 - can_run_on_erlang: true, 91 - can_run_on_javascript: true, 92 - uses_erlang_externals: false, 93 - uses_javascript_externals: false, 94 - }, 95 - }, 96 - ), 97 - target: None, 98 - }, 99 - ], 100 - names: Names { 101 - local_types: {}, 102 - imported_modules: {}, 103 - type_variables: {}, 104 - local_value_constructors: {}, 105 - reexport_aliases: {}, 106 - }, 107 - unused_definition_positions: {}, 108 - }, 109 - extra: ModuleExtra { 110 - module_comments: [], 111 - doc_comments: [], 112 - comments: [], 113 - empty_lines: [], 114 - new_lines: [ 115 - 0, 116 - 61, 117 - ], 118 - trailing_commas: [], 119 - }, 120 - }
+17
compiler-core/src/type_/tests/exhaustiveness.rs
··· 1940 1940 } "# 1941 1941 ); 1942 1942 } 1943 + 1944 + // https://github.com/gleam-lang/gleam/issues/5286 1945 + #[test] 1946 + fn reachable_bit_array_pattern() { 1947 + assert_no_warnings!( 1948 + r#" 1949 + pub fn main(x) { 1950 + case x { 1951 + <<_, "==">> -> 1 1952 + <<_, _, "=">> -> 2 1953 + // ^^^ This should be reachable 1954 + _ -> 3 1955 + } 1956 + } 1957 + "# 1958 + ); 1959 + }
-27
language-server/src/tests/snapshots/gleam_core__language_server__tests__action__extract_variable_starting_pipeline_steps.snap
··· 1 - --- 2 - source: compiler-core/src/language_server/tests/action.rs 3 - expression: "fn map(value, fn_over_value) { todo }\n\npub fn main() {\n 1\n |> Ok\n |> map(fn(value) { value + 2 })\n}" 4 - --- 5 - ----- BEFORE ACTION 6 - fn map(value, fn_over_value) { todo } 7 - 8 - pub fn main() { 9 - 1 10 - 11 - |> Ok 12 - ▔▔▔▔▔↑ 13 - |> map(fn(value) { value + 2 }) 14 - } 15 - 16 - 17 - ----- AFTER ACTION 18 - fn map(value, fn_over_value) { todo } 19 - 20 - pub fn main() { 21 - let result = 22 - 1 23 - |> Ok 24 - 25 - result 26 - |> map(fn(value) { value + 2 }) 27 - }