Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- uses: roc-lang/setup-roc@cbe782d6f165b89c87d99f50a59ac4f5f73b4427 # ratchet:roc-lang/setup-roc@v0.3.0
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-09-04-c125b82
nightly-tag: nightly-2026-09-22-e494788
- name: Install Rust toolchain
run: |
rustup toolchain install "${{ needs.rust-version.outputs.version }}" --profile minimal --target x86_64-unknown-linux-musl --component llvm-tools-preview
Expand All @@ -63,7 +63,7 @@ jobs:
- uses: roc-lang/setup-roc@cbe782d6f165b89c87d99f50a59ac4f5f73b4427 # ratchet:roc-lang/setup-roc@v0.3.0
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-09-04-c125b82
nightly-tag: nightly-2026-09-22-e494788
- name: Install Rust toolchain
shell: bash
run: |
Expand Down Expand Up @@ -108,7 +108,7 @@ jobs:
- uses: roc-lang/setup-roc@cbe782d6f165b89c87d99f50a59ac4f5f73b4427 # ratchet:roc-lang/setup-roc@v0.3.0
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-09-04-c125b82
nightly-tag: nightly-2026-09-22-e494788
- name: Install Rust toolchain
shell: bash
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
uses: roc-lang/setup-roc@bd311e2fb815a3d2255f7ee14a922f0b736e020b
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-09-04-c125b82
nightly-tag: nightly-2026-09-22-e494788

- name: Restore released docs
env:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ jobs:
uses: roc-lang/setup-roc@bd311e2fb815a3d2255f7ee14a922f0b736e020b
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-09-04-c125b82
nightly-tag: nightly-2026-09-22-e494788

- name: Install Zig
uses: mlugg/setup-zig@8d6198c65fb0feaa111df26e6b467fea8345e46f
Expand Down Expand Up @@ -215,7 +215,7 @@ jobs:
uses: roc-lang/setup-roc@bd311e2fb815a3d2255f7ee14a922f0b736e020b
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-09-04-c125b82
nightly-tag: nightly-2026-09-22-e494788

- name: Install Rust
shell: bash
Expand Down Expand Up @@ -260,7 +260,7 @@ jobs:
uses: roc-lang/setup-roc@bd311e2fb815a3d2255f7ee14a922f0b736e020b
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-09-04-c125b82
nightly-tag: nightly-2026-09-22-e494788

- name: Create docs staging tree
run: mkdir -p docs-site
Expand Down Expand Up @@ -408,7 +408,7 @@ jobs:
uses: roc-lang/setup-roc@bd311e2fb815a3d2255f7ee14a922f0b736e020b
with:
version: nightly-new-compiler
nightly-tag: nightly-2026-09-04-c125b82
nightly-tag: nightly-2026-09-22-e494788

- name: Download release metadata
uses: actions/download-artifact@v8
Expand Down
2 changes: 1 addition & 1 deletion examples/file-size.roc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ main! = |args| {
Ok({})
}

path_argument : List(OsStr) -> Try(Path, [MissingPathArgument, ..])
path_argument : List(OsStr) -> Try(Path, [MissingPathArgument])
path_argument = |args|
match args {
[first, ..] => Ok(Path.from_os_str(first))
Expand Down
6 changes: 5 additions & 1 deletion examples/http-client.roc
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,8 @@ reject_invalid_utf8! = || {
}

write_line! : Str => Try({}, _)
write_line! = |message| Stdout.line!(message)
write_line! = |message|
match Stdout.line!(message) {
Ok(value) => Ok(value)
Err(StdoutErr(err)) => Err(StdoutErr(err))
}
10 changes: 5 additions & 5 deletions platform/Cmd.roc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Cmd :: {
## ```roc
## Cmd.exec!("echo", ["hello world"])?
## ```
exec! : OsStr, List(OsStr) => Try({}, [ExecFailed({ command : Str, exit_code : I32 }), FailedToGetExitCode({ command : Str, err : IOErr }), ..])
exec! : OsStr, List(OsStr) => Try({}, [ExecFailed({ command : Str, exit_code : I32 }), FailedToGetExitCode({ command : Str, err : IOErr })])
exec! = |program, arguments| {
command = "${OsStr.display(program)} ${Str.join_with(arguments.map(OsStr.display), " ")}"

Expand All @@ -72,7 +72,7 @@ Cmd :: {
## .env("RUST_BACKTRACE", "1")
## .exec_cmd!()?
## ```
exec_cmd! : Cmd => Try({}, [ExecCmdFailed({ command : Str, exit_code : I32 }), FailedToGetExitCode({ command : Str, err : IOErr }), ..])
exec_cmd! : Cmd => Try({}, [ExecCmdFailed({ command : Str, exit_code : I32 }), FailedToGetExitCode({ command : Str, err : IOErr })])
exec_cmd! = |cmd| {
command = to_str(cmd)
exit_code = exec_exit_code!(cmd)?
Expand All @@ -98,7 +98,7 @@ Cmd :: {
##
## Stdout.line!("Echo output: ${cmd_output.stdout_utf8}")?
## ```
exec_output! : Cmd => Try({ stdout_utf8 : Str, stderr_utf8_lossy : Str }, [StdoutContainsInvalidUtf8({ cmd_str : Str, err : [BadUtf8({ problem : _, index : U64 })] }), NonZeroExitCode({ command : Str, exit_code : I32, stdout_utf8_lossy : Str, stderr_utf8_lossy : Str }), FailedToGetExitCode({ command : Str, err : IOErr }), ..])
exec_output! : Cmd => Try({ stdout_utf8 : Str, stderr_utf8_lossy : Str }, [StdoutContainsInvalidUtf8({ cmd_str : Str, err : [BadUtf8({ problem : _, index : U64 })] }), NonZeroExitCode({ command : Str, exit_code : I32, stdout_utf8_lossy : Str, stderr_utf8_lossy : Str }), FailedToGetExitCode({ command : Str, err : IOErr })])
exec_output! = |cmd| {
cmd_str = to_str(cmd)
exec_try = Host.cmd_exec_output!(to_host_cmd(cmd))
Expand Down Expand Up @@ -136,7 +136,7 @@ Cmd :: {
##
## Stdout.line!("${Str.inspect(cmd_output)}")? # {stderr_bytes: [], stdout_bytes: [72, 105, 10]}
## ```
exec_output_bytes! : Cmd => Try({ stderr_bytes : List(U8), stdout_bytes : List(U8) }, [NonZeroExitCodeB({ exit_code : I32, stdout_bytes : List(U8), stderr_bytes : List(U8) }), FailedToGetExitCodeB(IOErr), ..])
exec_output_bytes! : Cmd => Try({ stderr_bytes : List(U8), stdout_bytes : List(U8) }, [NonZeroExitCodeB({ exit_code : I32, stdout_bytes : List(U8), stderr_bytes : List(U8) }), FailedToGetExitCodeB(IOErr)])
exec_output_bytes! = |cmd| {
exec_try = Host.cmd_exec_output!(to_host_cmd(cmd))

Expand Down Expand Up @@ -164,7 +164,7 @@ Cmd :: {
## ```roc
## exit_code = Cmd.new("cat").arg("non_existent.txt").exec_exit_code!()?
## ```
exec_exit_code! : Cmd => Try(I32, [FailedToGetExitCode({ command : Str, err : IOErr }), ..])
exec_exit_code! : Cmd => Try(I32, [FailedToGetExitCode({ command : Str, err : IOErr })])
exec_exit_code! = |cmd| {
command = to_str(cmd)

Expand Down
20 changes: 10 additions & 10 deletions platform/Env.roc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Env :: [].{
## Reads the given environment variable.
##
## Returns `Err(VarNotFound(name))` if the variable is not set.
var! : OsStr => Try(OsStr, [VarNotFound(OsStr), EnvErr(IOErr), ..])
var! : OsStr => Try(OsStr, [VarNotFound(OsStr), EnvErr(IOErr)])
var! = |name|
match Host.env_var!(OsStr.to_raw(name)) {
Ok(raw) => Ok(OsStr.from_raw(raw))
Expand All @@ -42,7 +42,7 @@ Env :: [].{
}

## Reads the given environment variable as a string if its native value is valid text.
var_str! : OsStr => Try(Str, [VarNotFound(OsStr), EnvErr(IOErr), InvalidStr(U64), ..])
var_str! : OsStr => Try(Str, [VarNotFound(OsStr), EnvErr(IOErr), InvalidStr(U64)])
var_str! = |name|
match var!(name) {
Ok(value) =>
Expand All @@ -58,7 +58,7 @@ Env :: [].{
## from the environment.
##
## Returns `Err(CwdUnavailable)` if the cwd cannot be determined.
cwd! : () => Try(Path.Path, [CwdUnavailable, ..])
cwd! : () => Try(Path.Path, [CwdUnavailable])
cwd! = ||
match Host.env_cwd!() {
Ok(raw) => Ok(Path.from_raw(raw))
Expand All @@ -69,15 +69,15 @@ Env :: [].{
##
## Returns `Err(InvalidCwd(err))` when the path cannot be used as a working
## directory. The process-wide change remains in effect until changed again.
set_cwd! : Path.Path => Try({}, [InvalidCwd(IOErr), ..])
set_cwd! : Path.Path => Try({}, [InvalidCwd(IOErr)])
set_cwd! = |path|
Host.env_set_cwd!(Path.to_raw(path))
.map_err(|err| InvalidCwd(err))

## Gets the path to the currently-running executable.
##
## Returns `Err(ExePathUnavailable)` if the path cannot be determined.
exe_path! : () => Try(Path.Path, [ExePathUnavailable, ..])
exe_path! : () => Try(Path.Path, [ExePathUnavailable])
exe_path! = ||
match Host.env_exe_path!() {
Ok(raw) => Ok(Path.from_raw(raw))
Expand All @@ -90,7 +90,7 @@ Env :: [].{
## another value. Unlike [`exe_path!`](#exe_path!), it is returned as an
## [`OsStr`](OsStr), preserving the value exactly without treating it as a path.
## Returns `Err(ProgramNameUnavailable)` if the launcher supplied no first argument.
program_name! : () => Try(OsStr, [ProgramNameUnavailable, ..])
program_name! : () => Try(OsStr, [ProgramNameUnavailable])
program_name! = ||
match Host.env_program_name!() {
Ok(raw) => Ok(OsStr.from_raw(raw))
Expand All @@ -99,16 +99,16 @@ Env :: [].{

## Atomically create a private directory in the system temporary directory.
## The caller owns cleanup. Unix directories have mode 0700.
create_temp_dir! : () => Try(Path.Path, [TempDirErr(IOErr), ..])
create_temp_dir! : () => Try(Path.Path, [TempDirErr(IOErr)])
create_temp_dir! = || create_temp_dir_with_prefix!("roc-")

## Create a private temporary directory with a filename prefix.
create_temp_dir_with_prefix! : Str => Try(Path.Path, [TempDirErr(IOErr), ..])
create_temp_dir_with_prefix! : Str => Try(Path.Path, [TempDirErr(IOErr)])
create_temp_dir_with_prefix! = |prefix| create_temp_dir_in!(temp_dir!(), prefix)

## Create a private temporary directory under an existing parent directory.
## Prefixes cannot contain separators, colons, NUL, or be `.` or `..`.
create_temp_dir_in! : Path.Path, Str => Try(Path.Path, [TempDirErr(IOErr), ..])
create_temp_dir_in! : Path.Path, Str => Try(Path.Path, [TempDirErr(IOErr)])
create_temp_dir_in! = |parent, prefix|
Host.env_create_temp_dir!(Path.to_raw(parent), prefix).map_ok(Path.from_raw).map_err(|err| TempDirErr(err))

Expand All @@ -122,7 +122,7 @@ Env :: [].{
## Path.read_utf8!(file)
## })?
## ```
with_temp_dir! : (Path.Path => Try(a, err)) => Try(a, [TempDirErr(IOErr), CallbackErr(err), CleanupErr(IOErr, Path.Path), CallbackAndCleanupErr(err, IOErr, Path.Path), ..])
with_temp_dir! : (Path.Path => Try(a, err)) => Try(a, [TempDirErr(IOErr), CallbackErr(err), CleanupErr(IOErr, Path.Path), CallbackAndCleanupErr(err, IOErr, Path.Path)])
with_temp_dir! = |callback!| {
path = create_temp_dir!()?
result = callback!(path)
Expand Down
12 changes: 6 additions & 6 deletions platform/Http.roc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Http :: [].{
## request = Request.from_method(GET).with_uri("https://www.roc-lang.org")
## response = Http.send!(request)?
## ```
send! : Request => Try(Response, [InvalidUrl(Url.ParseErr), HttpErr(TransportErr), ..])
send! : Request => Try(Response, [InvalidUrl(Url.ParseErr), HttpErr(TransportErr)])
send! = |request| {
url = Url.parse(Request.uri(request)) ? InvalidUrl
canonical_url = Url.without_fragment(url)
Expand All @@ -41,7 +41,7 @@ Http :: [].{
##
## This uses Roc's builtin JSON encoder, so the value's type determines the
## encoder through static dispatch.
with_json_body : Request, _ => Try(Request, [JsonErr(_), ..])
with_json_body : Request, _ => Try(Request, [JsonErr(_)])
with_json_body = |request, value| {
body = Json.to_str_try(value) ? JsonErr

Expand All @@ -53,7 +53,7 @@ Http :: [].{
}

## Encode a value as JSON, attach it to the request body, and send it.
send_json! : Request, _ => Try(Response, [JsonErr(_), InvalidUrl(Url.ParseErr), HttpErr(TransportErr), ..])
send_json! : Request, _ => Try(Response, [JsonErr(_), InvalidUrl(Url.ParseErr), HttpErr(TransportErr)])
send_json! = |request, value| {
json_request = with_json_body(request, value)?

Expand All @@ -68,7 +68,7 @@ Http :: [].{
## ```roc
## hello_str = Http.get_utf8!("http://localhost:8000")?
## ```
get_utf8! : Url.Url => Try(Str, [BadBody(Str), InvalidUrl(Url.ParseErr), HttpErr(TransportErr), ..])
get_utf8! : Url.Url => Try(Str, [BadBody(Str), InvalidUrl(Url.ParseErr), HttpErr(TransportErr)])
get_utf8! = |url| {
response = send!(Request.from_method(GET).with_uri(Url.to_str(url)))?
body = Str.from_utf8(Response.body(response)) ? |_| BadBody("get_utf8!: response body was not valid UTF-8")
Expand All @@ -80,7 +80,7 @@ Http :: [].{
##
## This uses Roc's builtin JSON parser, so the expected result type
## determines the parser through static dispatch.
decode_json_response : Response => Try(_, [BadBody(Str), JsonErr(_), ..])
decode_json_response : Response => Try(_, [BadBody(Str), JsonErr(_)])
decode_json_response = |response| {
body = Str.from_utf8(Response.body(response)) ? |_| BadBody("decode_json_response: response body was not valid UTF-8")
decoded = Json.parse(body) ? JsonErr
Expand All @@ -97,7 +97,7 @@ Http :: [].{
## payload : Try({ foo : Str }, _)
## payload = Http.get!("http://localhost:8000")
## ```
get! : Url.Url => Try(_, [BadBody(Str), InvalidUrl(Url.ParseErr), HttpErr(TransportErr), JsonErr(_), ..])
get! : Url.Url => Try(_, [BadBody(Str), InvalidUrl(Url.ParseErr), HttpErr(TransportErr), JsonErr(_)])
get! = |url| {
response = send!(Request.from_method(GET).with_uri(Url.to_str(url)))?

Expand Down
11 changes: 2 additions & 9 deletions platform/Locale.roc
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ Locale :: { raw : Str }.{
## `POSIX` locales are not language tags and are ignored.
##
## Returns `Err(NotAvailable)` if the locale cannot be determined.
get! : () => Try(Locale, [NotAvailable, ..])
get! : () => Try(Locale, [NotAvailable])
get! = || {
raw = widen_locale_err(Host.locale_get!())?
raw = Host.locale_get!()?
Ok(Locale.{ raw })
}

Expand Down Expand Up @@ -213,13 +213,6 @@ parse_err_to_str = |err|
SubtagTooLong => "Locale subtags must be at most 8 characters"
}

widen_locale_err : Try(a, [NotAvailable]) -> Try(a, [NotAvailable, ..])
widen_locale_err = |result|
match result {
Ok(value) => Ok(value)
Err(NotAvailable) => Err(NotAvailable)
}

expect
match Locale.parse("en-US") {
Ok(locale) => Locale.to_str(locale) == "en-US"
Expand Down
Loading
Loading