changelog/v1.17.md
The release is dedicated to the memory of Chris Young, a man who inspired and believed in people. Without him, Gleam may not have ever existed.
Restrict custom documentation page path and source values so gleam docs build cannot escape the docs output directory or project root.
(evipepota and
Louis Pilfold)
Stricter deserialisation rules for files internal the build directory to reject corrupted data. (Abdelrahman Ahmed Aboelkasem, Aly, and Louis Pilfold)
Restrict publication tarball creation so they cannot contain files from outside the project root. (Abdelrahman Ahmed Aboelkasem, Aly, and Louis Pilfold)
Fixed a bug where the "Convert to case" code action would silently fail for
every inexhaustive let assignment in a module other than the first one.
(John Downey)
Fixed a bug where the JavaScript code generator would not emit semicolon after some expressions. (Andrey Kozhev)
Fixed a bug where the JavaScript prelude's BitArray$BitArray$data FFI
function would throw an Error using the wrong class.
(John Downey)
Fixed a bug where the JavaScript code generator could produce duplicate let
declarations for internal variables when a case expression was used as a
step in a pipeline.
(Eyup Can Akman)
Fixed a bug where the JavaScript code generator would use wrong constructor name in equality comparisons for imported variant with zero arguments and import alias. (Andrey Kozhev)
The compiler now suggest public values from imported modules when the variable is unknown. These values are suggested based on name and arity.
Considering this program:
import gleam/io
pub fn main() -> Nil {
println("Hello, World!")
}
The compiler will display this error message:
error: Unknown variable
┌─ /path/to/project/src/project.gleam:4:3
│
4 │ println("Hello, World!")
│ ^^^^^^^
The name `println` is not in scope here.
Did you mean one of these:
- io.println
(raphrous)
The inference of record update expressions is now more fault tolerant: if there's an error in the record being updated, the compiler can still able to analyse the fields that are being provided. (Giacomo Cavalieri)
The inference of clause guards is now more fault tolerant: if there's an error in a part of the guard expression, the compiler can still able to analyse the rest of the guard rather than stopping at the first error. (Giacomo Cavalieri)
It is now possible to use the todo keyword in constants, this will result in
an helpful error message rather than a syntax error.
(Giacomo Cavalieri)
The compiler now prints correctly qualified or aliased type names when printing warnings. For example:
import user
pub fn main() {
user.to_string(todo)
|> io.println
}
Will produce the following warning:
warning: Todo found
┌─ /src/warning/wrn.gleam:4:19
│
4 │ user.to_string(todo)
│ ^^^^ This code is incomplete
This code will crash if it is run. Be sure to finish it before
running your program.
Hint: I think its type is `user.User`.
Notice how the type hint is correctly qualified for the module the warning is raised in. (Giacomo Cavalieri)
When writing a constant record with an empty arguments list the compiler will no longer stop to analyse the entire module. (Giacomo Cavalieri)
The compiler now normalizes remaining-bytes bit-array checks for the
JavaScript backend so (bitSize - c) % 8 === 0 becomes bitSize % 8 === 0
when the constant offset c is congruent modulo 8. This produces more uniform
generated code for byte-aligned patterns.
(Daniele Scaratti)
The code generated for destructuring exhaustive patterns with let is now
less verbose on the JavaScript target.
The gleam dev command now accepts the --no-print-progress flag. When this
flag is passed, no progress information is printed.
(Giacomo Cavalieri)
Tables in the generated docs now look better on smaller screens. (Giacomo Cavalieri)
The comment in manifest.toml now instructs the user to include it in their
source control repository.
(Louis Pilfold)
The gleam deps outdated command now always prints a summary showing how many
packages have newer versions available. For example:
$ gleam deps outdated
1 of 12 packages have newer versions available.
Package Current Latest
------- ------- ------
gleam_stdlib 0.70.0 0.71.0
When no packages are outdated, only the summary line is printed:
$ gleam deps outdated
0 of 12 packages have newer versions available.
The package manager now has a specific error and automatic re-authentication flow for when a Hex session has been revoked or has expired. (Sahil Upasane)
New packages are created requesting Erlang/OTP version 29 on GitHub actions. (Louis Pilfold)
gleam publish will now better discover Git repository in monorepos. This
improves suggestions to push a tag, if it doesn't exist.
(Andrey Kozhev)
The gleam export escript command has been added for the creation of
escripts, BEAM
programs bundled into a single file.
(Louis Pilfold)
The language server now offers a "Fill labels" code action on constants to automatically fill in the missing labelled arguments from a record constructor. For example:
pub type Pokemon {
Pokemon(number: Int, name: String, hp: Int)
}
pub const cleffa = Pokemon(number: 173)
In this code snippet we haven't specified the name and hp fields, that's
an error! Triggering the "Fill labels" code action will result in the
following:
pub const cleffa = Pokemon(number: 173, name: todo, hp: todo)
When hovering a record update expression, the language server can now show the fields that are not being updated. For example:
pub type Person {
Person(name: String, age: Int)
}
pub fn happy_birthday_mom() {
let mom = Person(name: "Antonella", age: 60)
Person(..mom, age: 61)
// ^^^^^ Hovering this will show:
// Unchanged fields:
// - name
}
The language server can now help with completions when typing a list's tail:
pub fn main() {
let things_i_like = ["Gleam", "Ice Cream"]
["Dogs", ..t|]
// ^ Can now suggest a completion for `things_i_like`
}
The language server can now help with completions when typing a record update:
pub type User {
User(name: String, likes: List(String))
}
pub fn set_name(user: User, name: String) -> User {
User(..u|)
// ^ Can now suggest a completion for `user`
}
The language server now has a code action to remove a redundant record update. For example:
pub type User {
User(name: String, likes: List(String))
}
pub fn main() {
let lucy = User(name: "Lucy", likes: ["Gleam", "Ice Cream"])
let jak = User(..lucy, name: "Jak", likes: ["Gleam", "Dogs"])
// ^^^^^^ This record update is not needed!
}
This record update is not actually needed and will raise a warning, all fields are already specified. Triggering the code action anywhere on the expression will remove the unnecessary update:
pub type User {
User(name: String, likes: List(String))
}
pub fn main() {
let lucy = User(name: "Lucy", likes: ["Gleam", "Ice Cream"])
let jak = User(name: "Jak", likes: ["Gleam", "Dogs"])
}
When using the wrong operator in a guard, the language server can now suggest and apply an automatic fix. For example:
pub fn categorise() {
case pokemon {
Pokemon(name:, ..) if name == "rai" + "chu" -> todo
_ -> todo
}
}
Gleam has no operator overloading, and the operator used to join strings is
<>, not +. The language server can automatically fix this common mistake.
Triggering the code action on the guard will replace + with <>.
(Giacomo Cavalieri)
The language server now presents quick fix code actions before refactoring ones. (Giacomo Cavalieri)
The language server now allows to further pattern match on a discard by replacing it with the patterns it is discarding. For example:
pub fn list_names(x: Result(List(String), Nil)) {
case x {
Error(Nil) -> io.println("no names")
Ok(_) -> todo
// ^ Triggering the code action here
}
}
Triggering the code action will result in the following code:
pub fn list_names(x: Result(List(String), Nil)) {
case x {
Error(Nil) -> io.println("no names")
Ok([]) -> todo
Ok([first, ..rest]) -> todo
}
}
The "Generate variant" code action now automatically adds an import to use the generated variant if it is generated in a module from the different one. (Giacomo Cavalieri)
The language server no longer shows completions for deprecated values from dependencies. (Andrey Kozhev)
The language server now offers a code action to create unknown modules
when an import is added for a module that doesn't exist.
For example, if import wobble/woo is added to src/wiggle.gleam,
then a code action to create src/wobble/woo.gleam will be presented
when triggered over import wobble/woo.
(Cory Forsstrom)
The language server now supports finding references when triggered on an
aliased import. For example, in the following snippet, moving the cursor
over log and triggering "find references" will show all references of
io.println().
import gleam/io.{println as log}
fn main() {
log("Hello, world!")
//^^^ trigger here
}
The language server now supports textDocument/documentHighlight anywhere
that textDocument/references is available.
For example, triggering it with the cursor over any instance of vec will
result in all of the instances of it being highlighted.
fn to_cartesian(vec) {
// ^^^
let x = vec.rho * cos(vec.theta)
// ^^^ ^^^
let y = vec.rho * sin(vec.theta)
// ^^^ ^^^
#(x, y)
}
gleam-licences.html is now included with each release, detailing the
licences of the used dependencies.
(Louis Pilfold)Fixed a bug where gleam remove would fail with a confusing File IO error
if manifest.toml didn't exist yet (e.g. in a freshly-created project or
after the manifest had been deleted).
(Charlie Tonneslan)
Fixed a bug where the build tool would check for new major versions of a local
or git dependency on Hex when running gleam update.
(Giacomo Cavalieri)
Fixed a bug where the "pattern match on value" code action would generate
invalid code when used on a let assignment on the right hand side of another
let assignment.
(Giacomo Cavalieri)
Fixed a bug where the compiler wouldn't track the minimum required version when using list prepending in constants. (Giacomo Cavalieri)
Fixed a bug where the language server wouldn't let one extract record constructors as variables. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest completions for values from the language's prelude, even though their types were incompatible with the current context. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "wrap in anonymous" code action even when not hovering directly over a function. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "wrap in anonymous" code action when hovering over a record update. (Giacomo Cavalieri)
Fixed a bug where the compiler would generate invalid code for guards using lists with a tail. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "convert to case" code action even when not explicitly hovering an inexhaustive let assignment. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "add missing pattern" code action even when not explicitly hovering an inexhaustive case expression. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "unqualify" code action even when not explicitly hovering a qualified value. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "qualify" code action even when not explicitly hovering an unqualified type or constructor. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "generate dynamic decoder" code action even when not explicitly hovering a custom type. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "generate json encoder" code action even when not explicitly hovering a custom type. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "missing type parameter" code action even when not explicitly hovering a custom type. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "unwrap anonymous function" code action even when not explicitly hovering a custom type. (Giacomo Cavalieri)
Fixed a bug where the language server would suggest the "extract function" code action even when selecting multiple branches of a case expression, or patterns and guards of a case arm. (Giacomo Cavalieri)
Fixed a bug where the compiler would not warn for ints over the safe
JavaScript limit in BitArray segments with a unit option.
(Giacomo Cavalieri)
Fixed a bug where the compiler would incorrectly warn for ints over the
safe JavaScript limit in BitArray byte segments that aren't ints.
(Giacomo Cavalieri)
Fixed a confusing error message when writing a constant bit array with a size that is not a literal number. (Giacomo Cavalieri)
Fixed a confusing error message when writing bit arrays with an invalid unit. (Giacomo Cavalieri)
Fixed a confusing error message when writing a constant bit array with an invalid segment. (Giacomo Cavalieri)
Fixed a confusing error message when writing @external or @deprecated
annotations with arguments that are not string.
(Giacomo Cavalieri)
Fixed a bug where enabling javascript.typescript_declarations or
javascript.source_maps wouldn't generate their additional files unless the
build directory was manually deleted. The compiler now automatically rebuilds
the project when this configuration changes.
(daniellionel01)
Fixed a bug where using the bytes and unit options together on a bit array
segment could generate incorrect code on the JavaScript target.
(Surya Rose)
Fixed a bug where the JavaScript code generator could produce duplicate let
declarations for internal variables after a case expression whose subject
directly matches branch when existing variables with same exist in outer
scope.
(Andrey Kozhev)
Fixed a bug where gleam publish wrote the wrong application name into the
published package metadata for dependencies whose Hex package name differs
from their internal OTP application name. This caused Mix-based projects to
fail to build when they depended on Gleam packages with transitive
dependencies.
(Logan Bresnahan)
Fixed a bug where cli would fail to complete https connections from behind a proxy with self-signed certificates. The cli now defaults to using system trust stores for trusted CAs, allowing use in proxied network environments. (apsoras)
Fixed a bug where the language server's "add missing patterns" code action
would not be offered when the cursor was on an inexhaustive case expression
if another inexhaustive case appeared earlier in the same module.
(John Downey)