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

Configure Feed

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

1<!-- 2 SPDX-License-Identifier: Apache-2.0 3 SPDX-FileCopyrightText: 2020 The Gleam contributors 4--> 5 6# Changelog 7 8## v1.13.0 - 2025-10-19 9 10## v1.13.0-rc2 - 2025-10-06 11 12### Bug fixes 13 14- Fixed a bug where the "Extract function" code action would not properly 15 extract a `use` expression. 16 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 17 18- Fixed a bug where the "Extract function" code action would generate a function 19 with the wrong type when used on a use expression. 20 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 21 22- Fixed a bug where the error message for inexhaustive patterns could show 23 incorrect extra patterns in addition to the correct missing patterns. 24 ([Adi Salimgereyev](https://github.com/abs0luty)) 25 26- Fixed a bug where triggering the "Generate function" code action to generate 27 a function in a different module could cause the generated function to appear 28 in the middle of an existing function, resulting in invalid code. 29 ([Surya Rose](https://github.com/GearsDatapacks)) 30 31- Fixed a bug where the "turn into pipe" code action would not trigger inside 32 the final step of a pipeline. 33 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 34 35- Fixed a bug where the "pattern match on variable" code action would crash when 36 used on a variable followed by a case expression. 37 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 38 39## v1.13.0-rc1 - 2025-09-29 40 41### Compiler 42 43- The compiler now applies an optimisation known as "interference based pruning" 44 when compiling bit array pattern matching where matches are performed at the 45 start of bit arrays. 46 This optimisation drastically reduces compile times, memory usage and the 47 compiled code size, removing many redundant checks. 48 It is particularly important for network protocol applications where it is 49 typical to match on some fixed patterns at the start of the bitarray. 50 For example: 51 52 ```gleam 53 pub fn parser_headers(headers: BitArray, bytes: Int) -> Headers { 54 case headers { 55 <<"CONTENT_LENGTH" as header, 0, value:size(bytes), 0, rest:bytes>> 56 | <<"QUERY_STRING" as header, 0, value:size(bytes), 0, rest:bytes>> 57 | <<"REQUEST_URI" as header, 0, value:size(bytes), 0, rest:bytes>> 58 // ... 59 | <<"REDIRECT_STATUS" as header, 0, value:size(bytes), 0, rest:bytes>> 60 | <<"SCRIPT_NAME" as header, 0, value:size(bytes), 0, rest:bytes>> 61 -> [#(header, value), ..parse_headers(rest)] 62 } 63 } 64 ``` 65 66 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 67 68- The compiler now raises a warning for unreachable clauses that are matching 69 on bit array segments that could never match. Consider this example: 70 71 ```gleam 72 pub fn get_payload(packet: BitArray) -> Result(BitArray, Nil) { 73 case packet { 74 <<200, payload:bytes>> -> Ok(payload) 75 <<404, _:bits>> -> Error(Nil) 76 _ -> Ok(packet) 77 } 78 } 79 ``` 80 81 There's a subtle bug here. The second clause can never match since it's 82 impossible for the first byte of the bit array to have the value `404`. 83 The new error explains this nicely: 84 85 ```txt 86 warning: Unreachable pattern 87 ┌─ /src.gleam:4:5 88 89 4 │ <<404, _:bits>> -> Error(Nil) 90 │ ^^^^^^^^^^^^^^^ 91 │ │ 92 │ A 1 byte unsigned integer will never match this value 93 94 This pattern cannot be reached as it contains segments that will never 95 match. 96 97 Hint: It can be safely removed. 98 ``` 99 100 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 101 102- The compiler now raises a warning when a function's argument is only passed 103 along in a recursive call but not actually used for anything. For example: 104 105 ```gleam 106 import gleam/io 107 108 pub fn greet(x, times) { 109 case times { 110 0 -> Nil 111 _ -> { 112 io.println("Hello, Joe!") 113 greet(x, times - 1) 114 } 115 } 116 } 117 ``` 118 119 In this piece of code the `x` argument is actually never used, and the 120 compiler will raise the following warning: 121 122 ```txt 123 warning: Unused function argument 124 ┌─ /Users/giacomocavalieri/Desktop/prova/src/prova.gleam:3:14 125126 3 │ pub fn greet(x, times) { 127 │ ^ This argument is unused 128 129 This argument is passed to the function when recursing, but it's never used 130 for anything. 131 ``` 132 133 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 134 135- The compiler now emits a better error message for private types marked as 136 opaque. For example, the following piece of code: 137 138 ```gleam 139 opaque type Wibble { 140 Wobble 141 } 142 ``` 143 144 Would result in the following error: 145 146 ``` 147 error: Private opaque type 148 ┌─ /src/one/two.gleam:2:1 149150 2 │ opaque type Wibble { 151 │ ^^^^^^ You can safely remove this. 152 153 Only a public type can be opaque. 154 ``` 155 156 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 157 158- The parsing of opaque private types is now fault tolerant: having a private 159 opaque type in a module no longer stops the compiler from highlighting other 160 errors. 161 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 162 163- The compiler now emits a single warning for multiple negations in a row, while 164 previously it would emit multiple comments highlighting increasingly longer 165 spans. 166 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 167 168- Redundant `_ as x` patterns are now deprecated in favour of `x`. 169 ([eutampieri](https://github.com/eutampieri)) 170 171- The compiler will now raise warning for inefficient use of `list.length()` 172 when trying to check is list empty via `0 < list.length(list)` or 173 `list.length(list) > 0` as well as in other cases. For example, the following 174 code: 175 176 ```gleam 177 import gleam/list 178 179 pub fn main() { 180 let numbers = [1, 46] 181 let _ = 0 < list.length(numbers) 182 let _ = list.length(numbers) > 0 183 } 184 ``` 185 186 Would result in following warnings: 187 188 ``` 189 warning: Inefficient use of `list.length` 190 ┌─ /data/data/com.termux/files/home/test_gleam/src/test_gleam.gleam:5:13 191192 5 │ let _ = 0 < list.length(numbers) 193 │ ^^^^^^^^^^^^^^^^^^^^^^^^ 194 195 The `list.length` function has to iterate across the whole 196 list to calculate the length, which is wasteful if you only 197 need to know if the list is empty or not. 198 199 Hint: You can use `the_list != []` instead. 200 201 warning: Inefficient use of `list.length` 202 ┌─ /data/data/com.termux/files/home/test_gleam/src/test_gleam.gleam:6:13 203204 6 │ let _ = list.length(numbers) > 0 205 │ ^^^^^^^^^^^^^^^^^^^^^^^^ 206 207 The `list.length` function has to iterate across the whole 208 list to calculate the length, which is wasteful if you only 209 need to know if the list is empty or not. 210 211 Hint: You can use `the_list != []` instead. 212 ``` 213 214 ([Andrey Kozhev](https://github.com/ankddev)) 215 216- The compiler now provides an improved error message for when trying to define 217 a constant inside a function. For example, the following code: 218 219 ```gleam 220 pub fn deep_thought() -> Int { 221 const the_answer = 42 222 the_answer 223 } 224 ``` 225 226 Will produce this error message: 227 228 ```txt 229 error: Syntax error 230 ┌─ /src/file.gleam:2:3 231232 3 │ const the_answer = 43 233 │ ^^^^^ Constants are not allowed inside functions 234 235 All variables are immutable in Gleam, so constants inside functions are not 236 necessary. 237 Hint: Either move this into the global scope or use `let` binding instead. 238 ``` 239 240 ([Surya Rose](https://github.com/GearsDatapacks)) 241 242- The code generated for blocks on the JavaScript target has been improved and 243 is now smaller in certain cases. 244 ([Surya Rose](https://github.com/GearsDatapacks)) 245 246- Writing a type name followed by `()` now emits an error during analysis 247 rather than parsing, so it no longer stops the compiler from reporting errors 248 further in the code. 249 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 250 251- The compiler now shows a specific syntax error when trying to use an 252 angle-bracket syntax for generic types or function definitions: 253 254 ```txt 255 error: Syntax error 256 ┌─ /src/parse/error.gleam:2:12 257258 2 │ type Either<a, b> { 259 │ ^ I was expecting `(` here. 260 261 Type parameters use lowercase names and are surrounded by parentheses. 262 263 type Either(a, b) { 264 265 See: https://tour.gleam.run/data-types/generic-custom-types/ 266 ``` 267 268 ([Aaron Christiansen](https://github.com/AaronC81)) 269 270- Fault tolerance for analysis of labeled fields in variant patterns has 271 been improved. 272 ([sobolevn](https://github.com/sobolevn)) 273 274- Compiler now adds a hint when `#`-styled comments are used. This code: 275 276 ```gleam 277 fn some() { 278 let a = 1 279 # let b = 2 280 } 281 ``` 282 283 Now produces: 284 285 ```txt 286 error: Syntax error 287 ┌─ /src/main.gleam:3:5 288289 3 │ # let b = 2 290 │ ^^^ I was not expecting this 291 292 Found the keyword `let`, expected one of: 293 - `(` 294 Hint: Maybe you meant to create a comment? 295 Comments in Gleam start with `//`, not `#` 296 ``` 297 298 ([sobolevn](https://github.com/sobolevn)) 299 300- The `erlang.application_start_argument` parameter has been added to 301 `gleam.toml`. This is a string containing an Erlang term that will be written 302 into the package's Erlang `.app` file if `erlang.application_start_module` 303 has been set, replacing the default argument of `[]`. 304 ([Louis Pilfold](https://github.com/lpil)) 305 306- Generated code for the JavaScript target now includes a public API which can 307 be used for FFI interacting with Gleam custom types. For example, if you have 308 this Gleam code: 309 310 ```gleam 311 pub type Person { 312 Teacher(name: String, subject: String) 313 Student(name: String, age: Int) 314 } 315 ``` 316 317 You can use the new API to use the `Person` type in FFI code: 318 319 ```javascript 320 import {...} from "./person.mjs"; 321 322 // Constructing custom types 323 let teacher = Person$Teacher("Joe Armstrong", "Computer Science"); 324 let student = Person$Student("Louis Pilfold"); 325 326 let randomPerson = Math.random() > 0.5 ? teacher : student; 327 328 // Checking variants 329 let randomIsTeacher = Person$isTeacher(randomPerson); 330 331 // Getting fields 332 let teacherSubject = Person$Teacher$subject(teacher); 333 334 // The `name` field is shared so can be accessed from either variant 335 let personName = Person$name(randomPerson); 336 ``` 337 338 ([Surya Rose](https://github.com/GearsDatapacks)) 339 340### Build tool 341 342- New projects are generated using OTP28 on GitHub Actions. 343 ([Louis Pilfold](https://github.com/lpil)) 344 345- The build tool now has a new `hex owner transfer` subcommand to transfer 346 ownership of existing packages. 347 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 348 349- `gleam add` now adds `dependencies` and `dev_dependencies` as tables instead 350 of inline tables if they are missing. 351 ([Andrey Kozhev](https://github.com/ankddev)) 352 353- After dependency resolution the build tool will now print all packages added 354 and removed, and any versions changed. 355 ([Louis Pilfold](https://github.com/lpil)) 356 357- `gleam publish` now blocks publishing packages that contain the default main 358 function to prevent accidental publishing of unmodified template code. 359 ([Joohoon Cha](https://github.com/jcha0713)) 360 361- When generating documentation, the build tool will now print the names of 362 public type aliases instead of internal type names when annotating functions 363 and types. For example, for the following code: 364 365 ```gleam 366 import my_package/internal 367 368 pub type ExternalAlias = internal.InternalRepresentation 369 370 pub fn do_thing() -> ExternalAlias { ... } 371 ``` 372 373 This is what the build tool used to generate: 374 375 ```gleam 376 pub fn do_thing() -> @internal InternalRepresentation 377 ``` 378 379 Whereas now it will not use the internal name, and instead produce: 380 381 ```gleam 382 pub fn do_thing() -> ExternalAlias 383 ``` 384 385 ([Surya Rose](https://github.com/GearsDatapacks)) 386 387- Support has been added for using Tangled as a repository. 388 ([Naomi Roberts](https://github.com/naomieow)) 389 390### Language server 391 392- The language server now offers a code action to remove all the unreachable 393 clauses in a case expression. For example: 394 395 ```gleam 396 pub fn main() { 397 case find_user() { 398 Ok(user) -> todo 399 Ok(Admin) -> todo 400 // ^^^^^^^^^ This clause is unreachable 401 Ok(User) -> todo 402 // ^^^^^^^^ This clause is unreachable 403 Error(_) -> todo 404 } 405 } 406 ``` 407 408 Hovering over one of the unreachable clauses and triggering the code action 409 would remove all the unreachable clauses: 410 411 ```gleam 412 pub fn main() { 413 case find_user() { 414 Ok(user) -> todo 415 416 Error(_) -> todo 417 } 418 } 419 ``` 420 421 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 422 423- The "pattern match on variable" can now be triggered on lists. For example: 424 425 ```gleam 426 pub fn is_empty(list: List(a)) -> Bool { 427 // ^^^^ Triggering the action here 428 } 429 ``` 430 431 Triggering the action on the `list` argument would result in the following 432 code: 433 434 ```gleam 435 pub fn is_empty(list: List(a)) -> Bool { 436 case list { 437 [] -> todo 438 [first, ..rest] -> todo 439 } 440 } 441 ``` 442 443 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 444 445- The "pattern match on variable" code action can now be triggered on variables 446 introduced by other patterns. For example: 447 448 ```gleam 449 pub fn main() { 450 let User(name:, role:) = find_user("lucy") 451 // ^^^^ Triggering the action here 452 } 453 ``` 454 455 Triggering the action on another variable like `role` would result in the 456 following code: 457 458 ```gleam 459 pub fn main() { 460 let User(name:, role:) = find_user("lucy") 461 case role { 462 Admin -> todo 463 Member -> todo 464 } 465 } 466 ``` 467 468 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 469 470- The "pattern match on variable" code action can now be triggered on variables 471 in case expressions. For example: 472 473 ```gleam 474 pub fn main() { 475 case find_user() { 476 Ok(user) -> todo 477 Error(_) -> todo 478 } 479 } 480 ``` 481 482 Triggering the action on the `user` variable would result in the following 483 code: 484 485 ```gleam 486 pub fn main() { 487 case find_user() { 488 Ok(Admin) -> todo 489 Ok(Member) -> todo 490 Error(_) -> todo 491 } 492 } 493 ``` 494 495 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 496 497- The language server now offers a quick fix to remove `opaque` from a private 498 type: 499 500 ```gleam 501 opaque type Wibble { 502 // ^^^ This is an error! 503 Wobble 504 } 505 ``` 506 507 If you hover over the type and trigger the quick fix, the language server will 508 automatically remove the `opaque` keyword: 509 510 ```gleam 511 type Wibble { 512 Wobble 513 } 514 ``` 515 516 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 517 518- The language server now offers a code action to add the omitted labels in a 519 call. For example: 520 521 ```gleam 522 pub type User { 523 User(first_name: String, last_name: String, likes: List(String)) 524 } 525 526 pub fn main() { 527 let first_name = "Giacomo" 528 User(first_name, "Cavalieri", ["gleam"]) 529 //^^^^ Triggering the code action here 530 } 531 ``` 532 533 Triggering the code action on the `User` constructor will result in the 534 following code: 535 536 ```gleam 537 pub type User { 538 User(first_name: String, last_name: String, likes: List(String)) 539 } 540 541 pub fn main() { 542 let first_name = "Giacomo" 543 User(first_name:, last_name: "Cavalieri", likes: ["gleam"]) 544 } 545 ``` 546 547- The "inline variable" code action is now only suggested when hovering over the 548 relevant variable. 549 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 550 551- When hovering over a record field in a record access expression, the language 552 sever will now show the documentation for that field, if present. 553 ([Surya Rose](https://github.com/GearsDatapacks)) 554 555- Renaming a variable from a label shorthand (`name:`) no longer includes the 556 colon in the rename dialog (`name:` -> `name`) 557 ([fruno](https://github.com/frunobulax-the-poodle)) 558 559- The language server now offers a code action to collapse nested case 560 expressions. Take this example: 561 562 ```gleam 563 case user { 564 User(role: Admin, name:) -> 565 // Here the only thing we're doing is pattern matching on the 566 // `name` variable we've just defined in the outer pattern. 567 case name { 568 "Joe" -> "Hello, Joe!" 569 _ -> "Hello, stranger" 570 } 571 572 _ -> "You're not an admin!" 573 } 574 ``` 575 576 We could simplify this case expression and reduce nesting like so: 577 578 ```gleam 579 case user { 580 User(role: Admin, name: "Joe") -> "Hello, Joe!" 581 User(role: Admin, name: _) -> "Hello, stranger" 582 _ -> "You're not an admin!" 583 } 584 ``` 585 586 Now, if you hover over that pattern, the language server will offer the 587 "collapse nested case" action that will simplify your code like shown in the 588 example above. 589 590 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 591 592- The "Generate function" code action now allows generating function in other 593 modules. For example, given the following code: 594 595 ```gleam 596 // maths.gleam 597 pub fn add(a: Int, b: Int) -> Int { a + b } 598 599 // main.gleam 600 import maths 601 602 pub fn main() -> Int { 603 echo maths.add(1, 2) 604 echo maths.subtract(from: 2, subtract: 1) 605 // ^ Trigger the "Generate function" code action here 606 } 607 ``` 608 609 The language sever will edit the `maths.gleam` file: 610 611 ```gleam 612 pub fn add(a: Int, b: Int) -> Int { a + b } 613 614 pub fn subtract(from from: Int, subtract subtract: Int) -> Int { 615 todo 616 } 617 ``` 618 619 ([Surya Rose](https://github.com/GearsDatapacks)) 620 621- The "Add type annotations" and "Generate function" code actions now ignore 622 type variables defined in other functions, improving the generated code. 623 For example: 624 625 ```gleam 626 fn something(a: a, b: b, c: c) -> d { todo } 627 628 fn pair(a, b) { #(a, b) } 629 ``` 630 631 Previously, when triggering the "Add type annotations" code action on the 632 `pair` function, the language server would have generated: 633 634 ```gleam 635 fn pair(a: e, b: f) -> #(e, f) { #(a, b) } 636 ``` 637 638 However in 1.13, it will now generate: 639 640 ```gleam 641 fn pair(a: a, b: b) -> #(a, b) { #(a, b) } 642 ``` 643 644 ([Surya Rose](https://github.com/GearsDatapacks)) 645 646- You can now go to definition, rename, etc. from alternative patterns! 647 648 ```gleam 649 case wibble { 650 Wibble | Wobble -> 0 651 // ^- Previously you could not trigger actions from here 652 } 653 654 ``` 655 656 ([fruno](https://github.com/fruno-bulax)) 657 658- When showing types of values on hover, or adding type annotations, the language 659 server will now prefer public type aliases to internal types. For example, if 660 the "Add type annotations" code action was triggered on the following code: 661 662 ```gleam 663 import lustre/html 664 import lustre/element 665 import lustre/attribute 666 667 pub fn make_link(attribute, element) { 668 html.a([attribute], [elements]) 669 } 670 ``` 671 672 Previously, the following code would have been generated: 673 674 ```gleam 675 pub fn make_link( 676 attribute: vattr.Attribute, 677 element: vdom.Element(a) 678 ) -> vdom.Element(a) { 679 html.a([attribute], [elements]) 680 } 681 ``` 682 683 Which references internal types which should not be imported by the user. 684 However, now the language server will produce the following: 685 686 ```gleam 687 pub fn make_link( 688 attribute: attribute.Attribute, 689 element: element.Element(a) 690 ) -> element.Element(a) { 691 html.a([attribute], [elements]) 692 } 693 ``` 694 695 ([Surya Rose](https://github.com/GearsDatapacks)) 696 697- The language server now offers the `convert to case` code action only if a 698 single `let assert` expression is selected. 699 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 700 701- The language server now offers an "Extract function" code action to extract a 702 selected piece of code into a separate function. For example: 703 704 ```gleam 705 const head_byte_count = 256 706 707 pub fn get_head_of_file() { 708 let assert Ok(contents) = read_file() 709 710 case contents { 711 //^ Select from here 712 <<head:bytes-size(head_byte_count), _:bits>> -> Ok(head) 713 _ -> Error(Nil) 714 } 715 //^ Until here 716 } 717 ``` 718 719 Would become: 720 721 ```gleam 722 const head_byte_count = 256 723 724 pub fn get_head_of_file() { 725 let assert Ok(contents) = read_file() 726 727 function(contents) 728 } 729 730 fn function(contents: BitArray) -> Result(BitArray, Nil) { 731 case contents { 732 <<head:bytes-size(head_byte_count), _:bits>> -> Ok(head) 733 _ -> Error(Nil) 734 } 735 } 736 ``` 737 738 You can then use language server renaming to choose an appropriate name for 739 the new function. 740 741 ([Surya Rose](https://github.com/GearsDatapacks)) 742 743### Formatter 744 745- The formatter now removes needless multiple negations that are safe to remove. 746 For example, this snippet of code: 747 748 ```gleam 749 pub fn useless_negations() { 750 let lucky_number = --11 751 let lucy_is_a_star = !!!False 752 } 753 ``` 754 755 Is rewritten as: 756 757 ```gleam 758 pub fn useless_negations() { 759 let lucky_number = 11 760 let lucy_is_a_star = !False 761 } 762 ``` 763 764 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 765 766- Redundant `_ as x` patterns are rewritten to `x`. 767 ([eutampieri](https://github.com/eutampieri)) 768 769- The formatter no longer removes blocks from case clause guards. 770 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 771 772- The formatter now properly formats tuple return annotation with comments. 773 ([Andrey Kozhev](https://github.com/ankddev)) 774 775### Bug fixes 776 777- Fixed a bug where literals using `\u{XXXX}` syntax in bit array pattern 778 segments were not translated to Erlang's `\x{XXXX}` syntax correctly. 779 ([Benjamin Peinhardt](https://github.com/bcpeinhardt)) 780 781- Fixed a bug where `echo` could crash on JavaScript if the module contains 782 record variants with the same name as some built-in JavaScript objects. 783 ([Louis Pilfold](https://github.com/lpil)) 784 785- Fixed a bug where the compiler would highlight an entire double negation 786 expression as safe to remove, instead of just highlighting the double 787 negation. 788 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 789 790- Fixed a bug where the compiler would crash if there was an invalid version 791 requirement in a project's `gleam.toml`. 792 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 793 794- Fixed a bug where the compiler would suggest a discouraged project name as an 795 alternative to the reserved `gleam` name. 796 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 797 798- Fixed a bug where Forgejo source URLs in the HTML documentation could be 799 incorrectly structured. 800 ([Louis Pilfold](https://github.com/lpil)) 801 802- The compiler now emits an error when a module in the `src` directory imports 803 a dev dependency, while previously it would incorrectly let these 804 dependencies to be imported. 805 ([Surya Rose](https://github.com/GearsDatapacks)) 806 807- Erroneous extra fields in `gleam.toml` dependency specifications will no 808 longer be siltently ignored. An error is now returned highlighting the 809 problem instead. 810 ([Louis Pilfold](https://github.com/lpil)) 811 812- Fixed a bug where renaming a constant which is referenced in another module 813 inside a guard would generate invalid code. 814 ([Surya Rose](https://github.com/GearsDatapacks)) 815 816- Fixed a bug where `echo .. as ..` message will be omitted in browser target. 817 ([Andrey Kozhev](https://github.com/ankddev)) 818 819- Fixed a bug where renaming a variable used in a record update would produce 820 invalid code in certain situations. 821 ([Surya Rose](https://github.com/GearsDatapacks)) 822 823- Fixed a bug where adding `echo` to the subject of a `case` expression would 824 prevent variant inference from working correctly. 825 ([Surya Rose](https://github.com/GearsDatapacks)) 826 827- Fixed a bug where the compiler would suggest to use a discarded value defined 828 in a different function. 829 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 830 831- Fixed a bug where the formatter would format a panic message adding more 832 nesting than necessary. 833 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 834 835- Fixed a bug where the language server wouldn't offer the "unqualify" code 836 action if used on a type alias. 837 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 838 839- Fixed a bug where the language server would fail to rename an external 840 function with no body. 841 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 842 843- Fixed a bug where the compiler allowed to write a guard with an empty clause. 844 ([Tristan-Mihai Radulescu](https://github.com/Courtcircuits)) 845 846- Fixed a bug where switching from a hex dependency to a git dependency would 847 result in an error from the compiler. 848 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 849 850- Fixed a bug where the compiler would reference a redeclared variable in a let 851 assert message, instead of the original variable, on the Erlang target. 852 ([Danielle Maywood](https://github.com/DanielleMaywood)) 853 854- Fixed a bug where the compiler would report an imported module as unused if it 855 were used by private functions only. 856 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 857 858- Fixed a bug where the "Extract variable" code action would shadow existing 859 variables, constants and function names. 860 ([Matias Carlander](https://github.com/matiascr)) 861 862- Fixed a bug where the language server would not fill in the missing labels of 863 a pattern correctly, generating invalid code. 864 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 865 866- Fixed a bug where invalid code was being generated when using the "Extract 867 variable" code action inside an anonymous function. 868 ([Matias Carlander](https://github.com/matiascr)) 869 870- Fixed a bug where running `gleam update` would not properly update git 871 dependencies unless `gleam clean` was run first. 872 ([Surya Rose](https://github.com/GearsDatapacks)) 873 874- Fixed a bug where the compiler would produce wrong JavaScript code for binary 875 pattern matching expressions using literal strings and byte segments. 876 ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) 877 878- Fixed a bug where the build tool would crash when trying to add transitive dependency. 879 ([Andrey Kozhev](https://github.com/ankddev))