diff --git a/Cargo.lock b/Cargo.lock index 9cd10002c..4802fa0fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,11 +139,12 @@ checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "approx" -version = "0.5.1" +version = "0.6.0-rc2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +checksum = "94fbdd65cc59dcc820bfb0fd01315963d4f9898bf3399a47134c9836698c47df" dependencies = [ "num-traits", + "paste", ] [[package]] @@ -716,7 +717,7 @@ checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", - "libloading", + "libloading 0.8.9", ] [[package]] @@ -2030,7 +2031,7 @@ name = "hyperion-hot-reload" version = "0.1.0" dependencies = [ "flecs_ecs", - "libloading", + "libloading 0.9.0", ] [[package]] @@ -2538,6 +2539,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "libloading" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" +dependencies = [ + "cfg-if", + "windows-link", +] + [[package]] name = "libredox" version = "0.1.18" @@ -4096,7 +4107,7 @@ dependencies = [ "glob-match", "goblin", "libc", - "libloading", + "libloading 0.8.9", "log", "num-traits", "rand 0.8.7", @@ -4380,9 +4391,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ "winnow 1.0.4", ] diff --git a/Cargo.toml b/Cargo.toml index b074e8fae..acd198747 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,20 +53,23 @@ resolver = '2' [workspace.dependencies] aes = '0.9.2' -anyhow = '1.0.98' -approx = '0.5.1' -arc-swap = '1.7.1' -arrayvec = '0.7.4' +anyhow = "1.0.104" +# 0.6.0-rc2 rather than 0.5.1: it is the newest published version and 0.5.1 +# dates from 2022. Used only by tests, through assert_relative_eq, which 0.6 +# keeps. Drop the rc suffix when 0.6.0 ships. +approx = "0.6.0-rc2" +arc-swap = "1.9.2" +arrayvec = "0.7.8" base64 = "0.23.0" bitfield-struct = "0.13.0" -bitvec = '1.0.1' -boxcar = '0.2.13' -bumpalo = '3.16' +bitvec = "1.1.1" +boxcar = "0.2.14" +bumpalo = "3.20" byteorder = '1.5.0' -bytes = '1.8.0' +bytes = "1.12.1" cfb8 = '0.9.1' -colored = "3.0.0" -compact_str = '0.9.0' +colored = "3.1.1" +compact_str = "0.10.0" convert_case = "0.11.0" criterion = "0.8.2" derive-build = '0.1.1' @@ -75,11 +78,11 @@ dotenvy = '0.15.7' eframe = "0.35.0" egui = "0.35.0" egui_dock = "0.20.1" -enumset = '1.1.6' -fast_hilbert = '2.0.0' -fastrand = '2.1.0' +enumset = "1.1.14" +fast_hilbert = "2.1.0" +fastrand = "2.5.0" flume = "0.12.0" -futures-util = '0.3.31' +futures-util = "0.3.33" # Held at valence's version: `valence_protocol` exposes glam types (`Vec3`, # `Quat`, `BlockPos`) across its whole public API, and the vendored fork pins # 0.29.3. Anything newer here puts two glam crates in the tree and every @@ -89,51 +92,62 @@ glam = "0.29.3" heapless = "0.9.3" heed = "0.22.1" hex = '0.4.3' -humantime = '2.1.0' +humantime = "2.4.0" hyperion-proxy = { path = "crates/hyperion-proxy" } itertools = "0.15.0" kanal = '0.1.1' -libc = '0.2.172' -libdeflater = '1.24.0' -memmap2 = '0.9.5' -mio = { version = '1.0.3', features = ['os-poll', 'net'] } +# Held on the 0.2 line: libc 1.0.0-alpha.4 is published, but every other crate +# that reaches libc here (mio, heed, flecs_ecs_sys, getrandom, ndarray and two +# dozen more) requires 0.2, so taking the alpha only adds a second libc to the +# tree without removing the first. Move when the ecosystem does. +libc = "0.2.189" +libdeflater = "1.25.2" +memmap2 = "0.9.11" +mio = { version = "1.2.2", features = ['os-poll', 'net'] } more-asserts = '0.3.1' num-derive = "0.5.1" num-traits = '0.2.19' -num_cpus = "1.16.0" -once_cell = '1.21.3' -ordered-float = "5.0.0" -papaya = "0.2.1" -parking_lot = '0.12.3' +num_cpus = "1.17.0" +once_cell = "1.21.4" +ordered-float = "5.3.0" +papaya = "0.2.4" +parking_lot = "0.12.5" paste = "1.0.15" -plotters-bitmap = '0.3.6' -proc-macro2 = '1.0.95' -proptest = '1.5.0' -quote = '1.0.39' +plotters-bitmap = "0.3.7" +proc-macro2 = "1.0.107" +proptest = "1.11.0" +quote = "1.0.47" rand = "0.10.2" -rayon = '1.10.0' -rkyv = '0.8.8' -rustls = { version = '0.23.31', default-features = false, features = ['logging', 'std', 'tls12'] } -rustls-pki-types = '1.12.0' -rustls-webpki = '0.103.4' -serde = '1.0.217' -serde_json = '1.0.140' +rayon = "1.12.0" +rkyv = "0.8.17" +# Held on the 0.23 line: rustls 0.24.0-dev.1 is published but is a development +# placeholder, and tokio-rustls 0.26, hyper-rustls 0.27, reqwest 0.13 and +# rustls-platform-verifier 0.7 all require 0.23. Nothing can use 0.24 until +# those do. +rustls = { version = "0.23.42", default-features = false, features = ['logging', 'std', 'tls12'] } +rustls-pki-types = "1.15.1" +# Held on the 0.103 line for the same reason as rustls above: rustls 0.23 +# depends on 0.103, so 0.104.0-alpha.7 would put two webpki crates in the tree +# and hand hyperion a different WebPkiServerVerifier than rustls builds with. +rustls-webpki = "0.103.13" +serde = "1.0.229" +serde_json = "1.0.151" serial_test = "4.0.1" -slotmap = '1.0.7' +slotmap = "1.1.1" snafu = "0.9.2" syn = "3.0.3" tango-bench = "0.7.2" -tar = '0.4.41' -thiserror = '2.0.12' -thread_local = '1.1.8' +tar = "0.4.46" +thiserror = "2.0.19" +thread_local = "1.1.10" tikv-jemallocator = "0.7.0" -time = '0.3.41' -tokio = '1.45.0' -tokio-rustls = { version = '0.26.2', default-features = false, features = ['logging', 'tls12'] } +time = "0.3.54" +tokio = "1.53.1" +tokio-rustls = { version = "0.26.4", default-features = false, features = ['logging', 'tls12'] } toml = "1.1.3" -tracing-appender = '0.2.3' +tracing-appender = "0.2.5" sha2 = "0.11.0" -uuid = '1.16.0' +uuid = "1.24.0" [workspace.dependencies.bvh] @@ -144,22 +158,22 @@ path = 'crates/bvh-region' [workspace.dependencies.bytemuck] features = ['derive'] -version = '1.23.0' +version = "1.25.2" [workspace.dependencies.clap] features = ['derive'] -version = '4.5.38' +version = "4.6.4" [workspace.dependencies.derive_more] features = ['display', 'from', 'into', 'deref', 'deref_mut', 'debug', 'constructor', 'add'] -version = "2.0.1" +version = "2.1.1" [workspace.dependencies.divan] git = 'https://github.com/nvzqz/divan' [workspace.dependencies.flate2] default-features = false -version = '1.1.1' +version = "1.1.9" [workspace.dependencies.flecs_ecs] # Upstream main rather than the 0.2.2 release: it vendors flecs C 4.1.6 instead @@ -250,7 +264,7 @@ path = 'crates/packet-channel' [workspace.dependencies.indexmap] features = ['rayon'] -version = '2.9.0' +version = "2.14.0" [workspace.dependencies.ndarray] features = ["blas"] @@ -258,7 +272,7 @@ version = "0.17.2" [workspace.dependencies.plotters] default-features = false -version = '0.3.6' +version = "0.3.7" [workspace.dependencies.reqwest] # 0.13 renamed `rustls-tls` to `rustls`. @@ -274,26 +288,26 @@ version = "0.11.4" [workspace.dependencies.rustc-hash] features = ['nightly'] -version = '2.0.0' +version = "2.1.3" [workspace.dependencies.simd-utils] path = 'crates/simd-utils' [workspace.dependencies.syntect] default-features = false -version = '5.2.0' +version = "5.3.0" [workspace.dependencies.tokio-util] features = ['full'] -version = '0.7.15' +version = "0.7.19" [workspace.dependencies.tracing] features = ['release_max_level_info'] -version = '0.1.40' +version = "0.1.44" [workspace.dependencies.tracing-subscriber] features = ['env-filter', 'time'] -version = '0.3.18' +version = "0.3.23" [workspace.dependencies.tracing-tracy] features = ['timer-fallback'] diff --git a/crates/hyperion-hot-reload/Cargo.toml b/crates/hyperion-hot-reload/Cargo.toml index 752a4cad3..8ea857e21 100644 --- a/crates/hyperion-hot-reload/Cargo.toml +++ b/crates/hyperion-hot-reload/Cargo.toml @@ -20,7 +20,7 @@ crate-type = ["dylib", "rlib"] [dependencies] flecs_ecs.workspace = true -libloading = "0.8.9" +libloading = "0.9.0" [lints] workspace = true diff --git a/crates/hyperion-hot-reload/src/host.rs b/crates/hyperion-hot-reload/src/host.rs index 7e3fa2f16..6b066d487 100644 --- a/crates/hyperion-hot-reload/src/host.rs +++ b/crates/hyperion-hot-reload/src/host.rs @@ -37,14 +37,22 @@ pub enum LoadError { Refused(Refused), } +/// What the platform said, which is the only part of a load failure worth +/// reading. libloading 0.9 moved the `dlerror` text out of `Display` and behind +/// `source`, so `{e}` alone now prints "dlopen failed" and nothing else. +fn platform_detail(e: &libloading::Error) -> String { + core::error::Error::source(e).map_or_else(|| e.to_string(), |cause| format!("{e}: {cause}")) +} + impl core::fmt::Display for LoadError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { - Self::Dlopen(e) => write!(f, "could not open module: {e}"), + Self::Dlopen(e) => write!(f, "could not open module: {}", platform_detail(e)), Self::MissingEntry(e) => { write!( f, - "module exports no `hyperion_hot_module` entry point: {e}" + "module exports no `hyperion_hot_module` entry point: {}", + platform_detail(e) ) } Self::Abi(m) => write!(f, "refusing to load module: {m}"), @@ -53,7 +61,14 @@ impl core::fmt::Display for LoadError { } } -impl std::error::Error for LoadError {} +impl std::error::Error for LoadError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Dlopen(e) | Self::MissingEntry(e) => Some(e), + Self::Abi(_) | Self::Refused(_) => None, + } + } +} /// A successful load. #[derive(Debug)] diff --git a/crates/hyperion-hot-reload/tests/load_errors.rs b/crates/hyperion-hot-reload/tests/load_errors.rs new file mode 100644 index 000000000..84374a99e --- /dev/null +++ b/crates/hyperion-hot-reload/tests/load_errors.rs @@ -0,0 +1,39 @@ +//! What a failed load says, which is the only thing an operator has to go on. +//! +//! libloading 0.9 stopped putting the `dlerror` string in `Display` and moved it +//! behind `source`, so the naive `{e}` this crate used to write reduced every +//! failure to the words "dlopen failed". This pins the platform's own message +//! back into the text, and pins the error chain so a caller that walks `source` +//! reaches it too. + +use std::{error::Error, path::Path}; + +use flecs_ecs::core::World; +use hyperion_hot_reload::{HotReloader, LoadError}; + +#[test] +fn a_missing_dylib_names_the_path_the_loader_tried() { + let world = World::new(); + let mut reloader = HotReloader::new(); + + let path = Path::new("/nonexistent/hyperion-hot-reload-no-such-module.dylib"); + let error = reloader + .load(&world, path) + .expect_err("loading a path that does not exist must fail"); + + assert!( + matches!(error, LoadError::Dlopen(_)), + "expected a dlopen failure, got {error:?}" + ); + + let message = error.to_string(); + assert!( + message.contains("hyperion-hot-reload-no-such-module"), + "the message dropped the platform's own detail, leaving nothing to diagnose: {message}" + ); + + assert!( + error.source().is_some(), + "a caller walking the error chain reaches nothing: {message}" + ); +} diff --git a/crates/hyperion-item/Cargo.toml b/crates/hyperion-item/Cargo.toml index 24d1f298f..f6a6c008b 100644 --- a/crates/hyperion-item/Cargo.toml +++ b/crates/hyperion-item/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] flecs_ecs = { workspace = true } -bytemuck = "1.23.0" +bytemuck = "1.25.2" valence_protocol = { workspace = true } hyperion = { workspace = true } derive_more = { workspace = true } diff --git a/crates/simd-utils/Cargo.toml b/crates/simd-utils/Cargo.toml index 271cadcc3..767705f77 100644 --- a/crates/simd-utils/Cargo.toml +++ b/crates/simd-utils/Cargo.toml @@ -9,7 +9,7 @@ publish = false [dependencies] [dev-dependencies] -proptest = "1.5.0" +proptest = "1.11.0" aligned-vec = "0.6.4" [lints] diff --git a/flake.lock b/flake.lock index f8a9dbcd9..5dc7dae58 100644 --- a/flake.lock +++ b/flake.lock @@ -259,11 +259,11 @@ "tests": "tests" }, "locked": { - "lastModified": 1785167710, - "narHash": "sha256-+GibfstVTRaWmGaVUYTUr+ZxcZ5Ytz3QF0cSQNUJDow=", + "lastModified": 1785182436, + "narHash": "sha256-tce0UtK5lapbkMOI3c4/uEuZr6CQtBZvB0/BvfYUbak=", "owner": "indexable-inc", "repo": "index", - "rev": "3225f70fca2bc3a442e703ce09582c9d418e7221", + "rev": "5e3b95c1837f8f1d2b71f8bc6f1ef26f1439625a", "type": "github" }, "original": {