diff --git a/driver/justfile b/driver/justfile index ae3235a51..da5054f0d 100644 --- a/driver/justfile +++ b/driver/justfile @@ -6,7 +6,9 @@ set shell := ["bash", "-euo", "pipefail", "-c"] -export PATH := if env("RUST2_TS_TOOLCHAIN", "") == "" { env("PATH") } else { env("RUST2_TS_TOOLCHAIN") / "bin:" + env("PATH") } +# mbx's Cargo shim, which the dev shell exports, stays ahead of the nightly so cargo still builds through it. +cargo_shim := if env("RUST2_CARGO_SHIM", "") == "" { "" } else { env("RUST2_CARGO_SHIM") + ":" } +export PATH := if env("RUST2_TS_TOOLCHAIN", "") == "" { env("PATH") } else { cargo_shim + env("RUST2_TS_TOOLCHAIN") / "bin:" + env("PATH") } default: @just --list diff --git a/ffi/justfile b/ffi/justfile index 77e9a7bae..11f497675 100644 --- a/ffi/justfile +++ b/ffi/justfile @@ -6,7 +6,9 @@ set shell := ["bash", "-euo", "pipefail", "-c"] -export PATH := if env("RUST2_TS_TOOLCHAIN", "") == "" { env("PATH") } else { env("RUST2_TS_TOOLCHAIN") / "bin:" + env("PATH") } +# mbx's Cargo shim, which the dev shell exports, stays ahead of the nightly so cargo still builds through it. +cargo_shim := if env("RUST2_CARGO_SHIM", "") == "" { "" } else { env("RUST2_CARGO_SHIM") + ":" } +export PATH := if env("RUST2_TS_TOOLCHAIN", "") == "" { env("PATH") } else { cargo_shim + env("RUST2_TS_TOOLCHAIN") / "bin:" + env("PATH") } # The moq revision these recipes export by default: `just ts`'s, so both follow one moq. # just's own path is quoted wherever bash runs it: on Windows, its backslashes are escapes. diff --git a/flake.nix b/flake.nix index 04c2291da..4e7339f8f 100644 --- a/flake.nix +++ b/flake.nix @@ -316,6 +316,21 @@ RUST2_TS_TOOLCHAIN = tsToolchain; RUST2_TS_SYSROOT = rust2-ts-std; KOTLINX_COROUTINES = "${kotlinx-coroutines}"; + # The pinned toolchain goes on PATH ahead of everything the host had, which + # shadows the Cargo shim `mbx setup` installs. Put it back in front, as moq's dev + # shell does, so cargo builds through mbx's cache wherever the host set one up, + # the land gate included. The nightly projects' justfiles keep it ahead of their + # toolchain through RUST2_CARGO_SHIM. `setup --status` names the shim on its first + # line even when it is missing, and its exit code also fails over unrelated setup, + # so only the shim existing decides. + shellHook = '' + shim=$(mbx setup --status 2>/dev/null | sed -n '1s/.*: //p' || true) + if [ -x "$shim" ]; then + export RUST2_CARGO_SHIM=''${shim%/*} + export PATH="$RUST2_CARGO_SHIM:$PATH" + fi + unset shim + ''; }; # `just ts bench` adds Chrome and Firefox as engines. Apart for their size. devShells.bench = self.devShells.${system}.default.overrideAttrs (old: { diff --git a/go/justfile b/go/justfile index b78aab095..0273408ac 100644 --- a/go/justfile +++ b/go/justfile @@ -6,7 +6,9 @@ set shell := ["bash", "-euo", "pipefail", "-c"] -export PATH := if env("RUST2_TS_TOOLCHAIN", "") == "" { env("PATH") } else { env("RUST2_TS_TOOLCHAIN") / "bin:" + env("PATH") } +# mbx's Cargo shim, which the dev shell exports, stays ahead of the nightly so cargo still builds through it. +cargo_shim := if env("RUST2_CARGO_SHIM", "") == "" { "" } else { env("RUST2_CARGO_SHIM") + ":" } +export PATH := if env("RUST2_TS_TOOLCHAIN", "") == "" { env("PATH") } else { cargo_shim + env("RUST2_TS_TOOLCHAIN") / "bin:" + env("PATH") } default: @just --list diff --git a/quest/m0/checks/cache.md b/quest/m0/checks/cache.md index fccec89aa..59787dc88 100644 --- a/quest/m0/checks/cache.md +++ b/quest/m0/checks/cache.md @@ -13,4 +13,12 @@ gate has. PR code can write to it, a risk moq already accepts; mbx keys each com its compiler, target, and inputs. Local worktrees share it too, where the dev shell already can. -Public API: none. +Public API: `uniffi_macros`' `generate_and_include_scaffolding!` with the `trybuild` feature +resolves a relative path from the calling file, not from rustc's working directory. This is +breaking and has no `MIGRATE.md` entry yet. + +## Waiting + +- Maintainer: move the land host's mbx pin from 1.28.0 to 1.29.2 or later, then rerun `mbx setup` wherever a shim exists, since a shim runs the mbx its `mbx-target` file names. Check: `mbx --version` on the land host prints 1.29.2 or later, and the shim's `mbx-target` names that store path. 1.28.0 prints no real paths for files in a build script's `OUT_DIR` ([jdx/mr-boxington#896](https://github.com/jdx/mr-boxington/issues/896)). +- Maintainer: give rust2's land instance moq's per-repository mbx profile, `id = 9`, `command = "just ci"`, `cpuQuota = 800`, `memoryHigh = "8G"`, `memorySwapMax = "1G"`, with `enable = lib.mkDefault false` until the next item. Check: the host config's `rust2` entry has these values. +- Maintainer: enable that profile once [#426](https://github.com/moq-dev/rust2/pull/426) has merged. Check: a gate run's log shows `mbx[cache]: object cache: ...`. diff --git a/ts/justfile b/ts/justfile index 9c99d4015..66db0085f 100644 --- a/ts/justfile +++ b/ts/justfile @@ -6,7 +6,9 @@ set shell := ["bash", "-euo", "pipefail", "-c"] -export PATH := if env("RUST2_TS_TOOLCHAIN", "") == "" { env("PATH") } else { env("RUST2_TS_TOOLCHAIN") / "bin:" + env("PATH") } +# mbx's Cargo shim, which the dev shell exports, stays ahead of the nightly so cargo still builds through it. +cargo_shim := if env("RUST2_CARGO_SHIM", "") == "" { "" } else { env("RUST2_CARGO_SHIM") + ":" } +export PATH := if env("RUST2_TS_TOOLCHAIN", "") == "" { env("PATH") } else { cargo_shim + env("RUST2_TS_TOOLCHAIN") / "bin:" + env("PATH") } # The model fixture, its own workspace, which builds moq-net at the moq pin. model := "fixtures/model/Cargo.toml" diff --git a/uniffi/README.md b/uniffi/README.md index 593ef6701..f367a7ff5 100644 --- a/uniffi/README.md +++ b/uniffi/README.md @@ -88,6 +88,9 @@ uniffi-rs: - Scaffolding is written to a temporary file and renamed into place. Two trybuild cases expanding `generate_and_include_scaffolding!` on one UDL write it concurrently, and the in-place truncate let one include a partial file. +- `generate_and_include_scaffolding!` takes a path relative to the calling file, not to + rustc's working directory: trybuild compiles from inside the target directory, which a + build cache such as mbx moves out of the checkout. - The bindgen tests generate into a directory per test instead of one per language, so they run under nextest, which runs each test in its own process. - `uniffi_bindgen` has no `askama.toml`: its templates move from `src/**/templates` to diff --git a/uniffi/fixtures/uitests/tests/ui/fieldless_errors_used_in_callbacks_cant_have_fields.rs b/uniffi/fixtures/uitests/tests/ui/fieldless_errors_used_in_callbacks_cant_have_fields.rs index c7e7bdc40..7a8499860 100644 --- a/uniffi/fixtures/uitests/tests/ui/fieldless_errors_used_in_callbacks_cant_have_fields.rs +++ b/uniffi/fixtures/uitests/tests/ui/fieldless_errors_used_in_callbacks_cant_have_fields.rs @@ -1,5 +1,5 @@ -// Unfortunately, path is relative to a temporary build directory :-/ -uniffi_macros::generate_and_include_scaffolding!("../../../../uniffi/fixtures/uitests/src/errors.udl"); +// The path is relative to this file. +uniffi_macros::generate_and_include_scaffolding!("../../src/errors.udl"); fn main() { /* empty main required by `trybuild` */} diff --git a/uniffi/fixtures/uitests/tests/ui/interface_cannot_use_mut_self.rs b/uniffi/fixtures/uitests/tests/ui/interface_cannot_use_mut_self.rs index c0926b813..756a7e1d8 100644 --- a/uniffi/fixtures/uitests/tests/ui/interface_cannot_use_mut_self.rs +++ b/uniffi/fixtures/uitests/tests/ui/interface_cannot_use_mut_self.rs @@ -1,6 +1,6 @@ -// Unfortunately, path is relative to a temporary build directory :-/ -uniffi_macros::generate_and_include_scaffolding!("../../../../uniffi/fixtures/uitests/src/counter.udl"); +// The path is relative to this file. +uniffi_macros::generate_and_include_scaffolding!("../../src/counter.udl"); fn main() { /* empty main required by `trybuild` */} diff --git a/uniffi/fixtures/uitests/tests/ui/interface_not_sync_and_send.rs b/uniffi/fixtures/uitests/tests/ui/interface_not_sync_and_send.rs index 71710a653..b5da05dc2 100644 --- a/uniffi/fixtures/uitests/tests/ui/interface_not_sync_and_send.rs +++ b/uniffi/fixtures/uitests/tests/ui/interface_not_sync_and_send.rs @@ -1,8 +1,8 @@ use std::cell::Cell; -// Unfortunately, path is relative to a temporary build directory :-/ -uniffi_macros::generate_and_include_scaffolding!("../../../../uniffi/fixtures/uitests/src/counter.udl"); +// The path is relative to this file. +uniffi_macros::generate_and_include_scaffolding!("../../src/counter.udl"); fn main() { /* empty main required by `trybuild` */} diff --git a/uniffi/fixtures/uitests/tests/ui/interface_trait_not_sync_and_send.rs b/uniffi/fixtures/uitests/tests/ui/interface_trait_not_sync_and_send.rs index 540f9b2fe..1d337e832 100644 --- a/uniffi/fixtures/uitests/tests/ui/interface_trait_not_sync_and_send.rs +++ b/uniffi/fixtures/uitests/tests/ui/interface_trait_not_sync_and_send.rs @@ -1,5 +1,5 @@ -// Unfortunately, path is relative to a temporary build directory :-/ -uniffi_macros::generate_and_include_scaffolding!("../../../../uniffi/fixtures/uitests/src/trait.udl"); +// The path is relative to this file. +uniffi_macros::generate_and_include_scaffolding!("../../src/trait.udl"); fn main() { /* empty main required by `trybuild` */} diff --git a/uniffi/fixtures/uitests/tests/ui/non_hashable_record_key.rs b/uniffi/fixtures/uitests/tests/ui/non_hashable_record_key.rs index 8cbab4a10..59e69addb 100644 --- a/uniffi/fixtures/uitests/tests/ui/non_hashable_record_key.rs +++ b/uniffi/fixtures/uitests/tests/ui/non_hashable_record_key.rs @@ -1,4 +1,4 @@ -// Unfortunately, path is relative to a temporary build directory :-/ -uniffi_macros::generate_and_include_scaffolding!("../../../../uniffi/fixtures/uitests/src/records.udl"); +// The path is relative to this file. +uniffi_macros::generate_and_include_scaffolding!("../../src/records.udl"); fn main() { /* empty main required by `trybuild` */} diff --git a/uniffi/fixtures/uitests/tests/ui/trait_methods_no_trait.rs b/uniffi/fixtures/uitests/tests/ui/trait_methods_no_trait.rs index c9b39e573..e5f1af6c2 100644 --- a/uniffi/fixtures/uitests/tests/ui/trait_methods_no_trait.rs +++ b/uniffi/fixtures/uitests/tests/ui/trait_methods_no_trait.rs @@ -1,5 +1,5 @@ -// Unfortunately, path is relative to a temporary build directory :-/ -uniffi_macros::generate_and_include_scaffolding!("../../../../uniffi/fixtures/trait-methods/src/trait_methods.udl"); +// The path is relative to this file. +uniffi_macros::generate_and_include_scaffolding!("../../../trait-methods/src/trait_methods.udl"); fn main() { /* empty main required by `trybuild` */} diff --git a/uniffi/fixtures/uitests/tests/ui/trait_methods_unknown_trait.rs b/uniffi/fixtures/uitests/tests/ui/trait_methods_unknown_trait.rs index 2fd9299d1..768876131 100644 --- a/uniffi/fixtures/uitests/tests/ui/trait_methods_unknown_trait.rs +++ b/uniffi/fixtures/uitests/tests/ui/trait_methods_unknown_trait.rs @@ -1,5 +1,5 @@ -// Unfortunately, path is relative to a temporary build directory :-/ -uniffi_macros::generate_and_include_scaffolding!("../../../../uniffi/fixtures/uitests/src/trait_methods_unknown_trait.udl"); +// The path is relative to this file. +uniffi_macros::generate_and_include_scaffolding!("../../src/trait_methods_unknown_trait.udl"); fn main() { /* empty main required by `trybuild` */} diff --git a/uniffi/fixtures/uitests/tests/ui/trait_methods_unknown_trait.stderr b/uniffi/fixtures/uitests/tests/ui/trait_methods_unknown_trait.stderr index c8aaa57c4..f9f62b6d5 100644 --- a/uniffi/fixtures/uitests/tests/ui/trait_methods_unknown_trait.stderr +++ b/uniffi/fixtures/uitests/tests/ui/trait_methods_unknown_trait.stderr @@ -1,7 +1,7 @@ -error: Failed to generate scaffolding from UDL file at ../../../../uniffi/fixtures/uitests/src/trait_methods_unknown_trait.udl: parsing udl file ../../../../uniffi/fixtures/uitests/src/trait_methods_unknown_trait.udl: Invalid trait name: PartialEq +error: Failed to generate scaffolding from UDL file at ../../src/trait_methods_unknown_trait.udl: parsing udl file $DIR/tests/ui/../../src/trait_methods_unknown_trait.udl: Invalid trait name: PartialEq --> tests/ui/trait_methods_unknown_trait.rs:2:1 | -2 | uniffi_macros::generate_and_include_scaffolding!("../../../../uniffi/fixtures/uitests/src/trait_methods_unknown_trait.udl"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2 | uniffi_macros::generate_and_include_scaffolding!("../../src/trait_methods_unknown_trait.udl"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this error originates in the macro `uniffi_macros::generate_and_include_scaffolding` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/uniffi/fixtures/uitests/tests/ui/typedef_extern.rs b/uniffi/fixtures/uitests/tests/ui/typedef_extern.rs index 6018e191a..405b51ea6 100644 --- a/uniffi/fixtures/uitests/tests/ui/typedef_extern.rs +++ b/uniffi/fixtures/uitests/tests/ui/typedef_extern.rs @@ -1,4 +1,4 @@ -// Unfortunately, path is relative to a temporary build directory :-/ -uniffi_macros::generate_and_include_scaffolding!("../../../../uniffi/fixtures/uitests/src/typedef_extern.udl"); +// The path is relative to this file. +uniffi_macros::generate_and_include_scaffolding!("../../src/typedef_extern.udl"); fn main() { /* empty main required by `trybuild` */} diff --git a/uniffi/fixtures/uitests/tests/ui/typedef_extern.stderr b/uniffi/fixtures/uitests/tests/ui/typedef_extern.stderr index 779ac679a..7fa8435bf 100644 --- a/uniffi/fixtures/uitests/tests/ui/typedef_extern.stderr +++ b/uniffi/fixtures/uitests/tests/ui/typedef_extern.stderr @@ -1,4 +1,4 @@ -error: Failed to generate scaffolding from UDL file at ../../../../uniffi/fixtures/uitests/src/typedef_extern.udl: parsing udl file ../../../../uniffi/fixtures/uitests/src/typedef_extern.udl: `typedef extern` is no longer supported. +error: Failed to generate scaffolding from UDL file at ../../src/typedef_extern.udl: parsing udl file $DIR/tests/ui/../../src/typedef_extern.udl: `typedef extern` is no longer supported. You must replace `extern` with the type of the object: * "enum" for Enums. * "record", "dictionary" or "struct" for Records. @@ -24,7 +24,7 @@ error: Failed to generate scaffolding from UDL file at ../../../../uniffi/fixtur See https://mozilla.github.io/uniffi-rs/next/types/custom_types.html for more. --> tests/ui/typedef_extern.rs:2:1 | -2 | uniffi_macros::generate_and_include_scaffolding!("../../../../uniffi/fixtures/uitests/src/typedef_extern.udl"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2 | uniffi_macros::generate_and_include_scaffolding!("../../src/typedef_extern.udl"); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: this error originates in the macro `uniffi_macros::generate_and_include_scaffolding` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/uniffi/uniffi_macros/src/lib.rs b/uniffi/uniffi_macros/src/lib.rs index 0bc223730..58b5d116b 100644 --- a/uniffi/uniffi_macros/src/lib.rs +++ b/uniffi/uniffi_macros/src/lib.rs @@ -10,7 +10,7 @@ //! Macros for `uniffi`. #[cfg(feature = "trybuild")] -use camino::Utf8Path; +use camino::Utf8PathBuf; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, LitStr}; @@ -275,8 +275,9 @@ pub fn use_remote_type(tokens: TokenStream) -> TokenStream { /// /// This is a convenience macro designed for writing `trybuild`-style tests and /// probably shouldn't be used for production code. Given the path to a `.udl` file, -/// if will run `uniffi-bindgen` to produce the corresponding Rust scaffolding and then -/// include it directly into the calling file. Like so: +/// relative to the calling file as `include_str!`'s is, it will run `uniffi-bindgen` to +/// produce the corresponding Rust scaffolding and then include it directly into the calling +/// file. Like so: /// /// ```rs /// uniffi_macros::generate_and_include_scaffolding!("path/to/my/interface.udl"); @@ -285,8 +286,19 @@ pub fn use_remote_type(tokens: TokenStream) -> TokenStream { #[cfg(feature = "trybuild")] pub fn generate_and_include_scaffolding(udl_file: TokenStream) -> TokenStream { let udl_file = syn::parse_macro_input!(udl_file as LitStr); - let udl_file_string = udl_file.value(); - let udl_file_path = Utf8Path::new(&udl_file_string); + // Not relative to rustc's working directory, which is trybuild's project inside the target + // directory, and that need not sit in the checkout. + let Some(udl_file_path) = proc_macro::Span::call_site() + .local_file() + .and_then(|file| Utf8PathBuf::from_path_buf(file).ok()) + .and_then(|file| Some(file.parent()?.join(udl_file.value()))) + else { + return quote! { + compile_error!("generate_and_include_scaffolding! needs a UTF-8 path to the invoking file"); + } + .into(); + }; + let udl_file_path = udl_file_path.as_path(); if std::env::var("OUT_DIR").is_err() { quote! { compile_error!("This macro assumes the crate has a build.rs script, but $OUT_DIR is not present");