From 82d11768486560c18d94fbc76ba7da410a86727d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Nov 2025 13:42:59 +0100 Subject: [PATCH 01/13] epoll: use more idiomatic way to consume iterator --- src/tools/miri/src/shims/unix/linux_like/epoll.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/shims/unix/linux_like/epoll.rs b/src/tools/miri/src/shims/unix/linux_like/epoll.rs index 52b761fa08a1c..b0383c1ba4a12 100644 --- a/src/tools/miri/src/shims/unix/linux_like/epoll.rs +++ b/src/tools/miri/src/shims/unix/linux_like/epoll.rs @@ -181,13 +181,13 @@ impl EpollInterestTable { .borrow_mut() .extract_if(range_for_id(id), |_, _| true) // Consume the iterator. - .for_each(|_| ()); + .for_each(drop); epoll .ready_set .borrow_mut() .extract_if(range_for_id(id), |_| true) // Consume the iterator. - .for_each(|_| ()); + .for_each(drop); } } } From e4dbb8296270e6ae80347769bcebec172db59168 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Nov 2025 15:27:01 +0100 Subject: [PATCH 02/13] 'cargo update' the main crates --- src/tools/miri/Cargo.lock | 712 +++++++++++++-------------- src/tools/miri/cargo-miri/Cargo.lock | 403 ++++++--------- 2 files changed, 472 insertions(+), 643 deletions(-) diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index a2b02f286d659..84ccb28a26924 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -44,20 +44,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "710e8eae58854cdc1790fcb56cca04d712a17be849eeb81da2a724bf4bae2bc4" dependencies = [ "anstyle", - "unicode-width 0.2.1", + "unicode-width", ] [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "autocfg" @@ -67,9 +67,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backtrace" -version = "0.3.75" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -77,7 +77,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -91,15 +91,15 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bstr" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "regex-automata", @@ -114,11 +114,11 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "camino" -version = "1.1.10" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -166,10 +166,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.16" +version = "1.2.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -177,9 +178,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -189,9 +190,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "num-traits", ] @@ -218,18 +219,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.41" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.41" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" dependencies = [ "anstyle", "clap_lex", @@ -238,9 +239,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cmake" @@ -253,13 +254,13 @@ dependencies = [ [[package]] name = "codespan-reporting" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" +checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" dependencies = [ "serde", "termcolor", - "unicode-width 0.2.1", + "unicode-width", ] [[package]] @@ -273,7 +274,7 @@ dependencies = [ "eyre", "indenter", "once_cell", - "owo-colors 4.2.2", + "owo-colors", "tracing-error", ] @@ -284,21 +285,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427" dependencies = [ "once_cell", - "owo-colors 4.2.2", + "owo-colors", "tracing-core", "tracing-error", ] -[[package]] -name = "colored" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" -dependencies = [ - "lazy_static", - "windows-sys 0.59.0", -] - [[package]] name = "colored" version = "3.0.0" @@ -323,7 +314,7 @@ dependencies = [ "encode_unicode", "libc", "once_cell", - "unicode-width 0.2.1", + "unicode-width", "windows-sys 0.59.0", ] @@ -353,9 +344,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -363,11 +354,12 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.173" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64ed3da1c337cbaae7223cdcff8b4dddf698d188cd3eaddd1116f6b0295950" +checksum = "47ac4eaf7ebe29e92f1b091ceefec7710a53a6f6154b2460afda626c113b65b9" dependencies = [ "cc", + "cxx-build", "cxxbridge-cmd", "cxxbridge-flags", "cxxbridge-macro", @@ -377,9 +369,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.173" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae0a26a75a05551f5ae3d75b3557543d06682284eaa7419113162d602cb45766" +checksum = "2abd4c3021eefbac5149f994c117b426852bca3a0aad227698527bca6d4ea657" dependencies = [ "cc", "codespan-reporting", @@ -392,9 +384,9 @@ dependencies = [ [[package]] name = "cxxbridge-cmd" -version = "1.0.173" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "952d408b6002b7db4b36da07c682a9cbb34f2db0efa03e976ae50a388414e16c" +checksum = "6f12fbc5888b2311f23e52a601e11ad7790d8f0dbb903ec26e2513bf5373ed70" dependencies = [ "clap", "codespan-reporting", @@ -406,20 +398,19 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.173" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccbd201b471c75c6abb6321cace706d1982d270e308b891c11a3262d320f5265" +checksum = "83d3dd7870af06e283f3f8ce0418019c96171c9ce122cfb9c8879de3d84388fd" [[package]] name = "cxxbridge-macro" -version = "1.0.173" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bea8b915bbc4cb4288f242aa7ca18b23ecc6965e4d6e7c1b07905e3fe2e0c41" +checksum = "a26f0d82da663316786791c3d0e9f9edc7d1ee1f04bdad3d2643086a69d6256c" dependencies = [ "indexmap", "proc-macro2", "quote", - "rustversion", "syn", ] @@ -441,7 +432,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -469,12 +460,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -493,6 +484,12 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "find-msvc-tools" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" + [[package]] name = "fnv" version = "1.0.7" @@ -507,9 +504,9 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -543,26 +540,26 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasip2", ] [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "git2" @@ -581,15 +578,15 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.4" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -600,9 +597,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -613,11 +610,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -628,42 +624,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -673,9 +665,9 @@ dependencies = [ [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -694,15 +686,15 @@ dependencies = [ [[package]] name = "indenter" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.10.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", "hashbrown", @@ -717,7 +709,7 @@ dependencies = [ "console", "number_prefix", "portable-atomic", - "unicode-width 0.2.1", + "unicode-width", "web-time", ] @@ -732,9 +724,9 @@ dependencies = [ [[package]] name = "ipc-channel" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1c98b70019c830a1fc39cecfe1f60ff99c4122f0a189697c810c90ec545c14" +checksum = "f93600b5616c2d075f8af8dbd23c1d69278c5d24e4913d220cbc60b14c95c180" dependencies = [ "bincode", "crossbeam-channel", @@ -756,19 +748,19 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ "once_cell", "wasm-bindgen", @@ -788,9 +780,9 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.174" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libffi" @@ -826,19 +818,19 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.2", + "windows-link 0.2.1", ] [[package]] name = "libredox" -version = "0.1.4" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ "bitflags", "libc", @@ -846,9 +838,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.22" +version = "1.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" +checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" dependencies = [ "cc", "libc", @@ -858,40 +850,39 @@ dependencies = [ [[package]] name = "link-cplusplus" -version = "1.0.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6f6da007f968f9def0d65a05b187e2960183de70c160204ecfccf0ee330212" +checksum = "7f78c730aaa7d0b9336a299029ea49f9ee53b0ed06e9202e8cb7db9bae7b8c82" dependencies = [ "cc", ] [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "measureme" @@ -909,9 +900,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" @@ -933,13 +924,13 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] @@ -951,10 +942,10 @@ dependencies = [ "capstone", "chrono", "chrono-tz", - "colored 3.0.0", + "colored", "directories", "genmc-sys", - "getrandom 0.3.3", + "getrandom 0.3.4", "ipc-channel", "libc", "libffi", @@ -1001,9 +992,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] @@ -1022,9 +1013,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.109" +version = "0.9.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", @@ -1040,30 +1031,15 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "owo-colors" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" - -[[package]] -name = "owo-colors" -version = "4.2.2" +version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e" - -[[package]] -name = "pad" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3" -dependencies = [ - "unicode-width 0.1.14", -] +checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -1071,22 +1047,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perf-event-open-sys" @@ -1135,9 +1111,9 @@ checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -1153,28 +1129,27 @@ dependencies = [ [[package]] name = "prettydiff" -version = "0.7.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abec3fb083c10660b3854367697da94c674e9e82aa7511014dc958beeb7215e9" +checksum = "ac17546d82912e64874e3d5b40681ce32eac4e5834344f51efcf689ff1550a65" dependencies = [ - "owo-colors 3.5.0", - "pad", + "owo-colors", ] [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -1187,9 +1162,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha", "rand_core", @@ -1211,34 +1186,34 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] name = "redox_syscall" -version = "0.5.13" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -1248,9 +1223,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -1259,15 +1234,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "rustc-demangle" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" @@ -1298,22 +1273,22 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -1329,33 +1304,44 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scratch" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f6280af86e5f559536da57a45ebc84948833b3bee313a7dd25232e09c878a52" +checksum = "d68f2ec51b097e4c1a75b681a8bec621909b5e91f15bb7b840c4f2f7b01148b2" [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1364,14 +1350,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.141" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -1414,9 +1401,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "strsim" @@ -1426,9 +1413,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.104" +version = "2.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" dependencies = [ "proc-macro2", "quote", @@ -1448,15 +1435,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.20.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1479,11 +1466,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.17", ] [[package]] @@ -1499,9 +1486,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -1529,9 +1516,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -1580,15 +1567,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ui_test" -version = "0.30.2" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b56a6897cc4bb6f8daf1939b0b39cd9645856997f46f4d0b3e3cb7122dfe9251" +checksum = "44eb652e1a8799d4e47f20851370e86247cbc5270ce677ab1e9409a6d45a9649" dependencies = [ "annotate-snippets", "anyhow", @@ -1596,7 +1583,7 @@ dependencies = [ "cargo-platform", "cargo_metadata", "color-eyre", - "colored 2.2.0", + "colored", "comma", "crossbeam-channel", "indicatif", @@ -1612,31 +1599,26 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -1647,11 +1629,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.17.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "js-sys", "wasm-bindgen", ] @@ -1681,45 +1663,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1727,22 +1696,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] @@ -1759,41 +1728,64 @@ dependencies = [ [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "windows" -version = "0.58.0" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ "windows-core", - "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.58.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", + "windows-link 0.1.3", "windows-result", "windows-strings", - "windows-targets 0.52.6", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core", + "windows-link 0.1.3", + "windows-threading", ] [[package]] name = "windows-implement" -version = "0.58.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -1802,9 +1794,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.58.0" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -1812,22 +1804,43 @@ dependencies = [ ] [[package]] -name = "windows-result" +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-targets 0.52.6", + "windows-core", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", ] [[package]] name = "windows-strings" -version = "0.1.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-result", - "windows-targets 0.52.6", + "windows-link 0.1.3", ] [[package]] @@ -1836,16 +1849,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] name = "windows-sys" -version = "0.60.2" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets 0.53.2", + "windows-link 0.2.1", ] [[package]] @@ -1854,30 +1867,23 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] -name = "windows-targets" -version = "0.53.2" +name = "windows-threading" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link 0.1.3", ] [[package]] @@ -1886,84 +1892,42 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -1971,33 +1935,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -2005,9 +1959,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", @@ -2017,18 +1971,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", @@ -2058,9 +2012,9 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -2069,9 +2023,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.2" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -2080,9 +2034,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock index ea9c04a3cb515..1f1c5ac50d3c8 100644 --- a/src/tools/miri/cargo-miri/Cargo.lock +++ b/src/tools/miri/cargo-miri/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "autocfg" @@ -16,17 +16,17 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "camino" -version = "1.1.10" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -84,9 +84,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "directories" @@ -106,7 +106,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.60.2", + "windows-sys", ] [[package]] @@ -128,22 +128,23 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "erased-serde" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" +checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" dependencies = [ "serde", + "serde_core", "typeid", ] [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys", ] [[package]] @@ -154,9 +155,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -169,32 +170,32 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasip2", ] [[package]] name = "hashbrown" -version = "0.15.4" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -205,9 +206,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -218,11 +219,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -233,42 +233,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -278,9 +274,9 @@ dependencies = [ [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -299,9 +295,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", "hashbrown", @@ -315,15 +311,15 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "libc" -version = "0.2.174" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libredox" -version = "0.1.4" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ "bitflags", "libc", @@ -331,21 +327,21 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "num-traits" @@ -379,33 +375,33 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -418,9 +414,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "redox_users" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", @@ -429,9 +425,9 @@ dependencies = [ [[package]] name = "rustc-build-sysroot" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd41ead66a69880951b2f7df3139db401d44451b4da123344d27eaa791b89c95" +checksum = "3b881c015c729b43105bbd3702a9bdecee28fafaa21126d1d62e454ec011a4b7" dependencies = [ "anyhow", "rustc_version", @@ -457,15 +453,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.60.2", + "windows-sys", ] [[package]] @@ -485,30 +481,33 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] [[package]] name = "serde-untagged" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "299d9c19d7d466db4ab10addd5703e4c615dec2a5a16dbbafe191045e87ee66e" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" dependencies = [ "erased-serde", "serde", + "serde_core", "typeid", ] @@ -522,11 +521,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -535,14 +543,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.141" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -562,15 +571,15 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "syn" -version = "2.0.104" +version = "2.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" dependencies = [ "proc-macro2", "quote", @@ -590,31 +599,31 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.20.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys", ] [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -623,9 +632,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -681,9 +690,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-xid" @@ -693,13 +702,14 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -725,200 +735,65 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys", ] [[package]] -name = "windows-sys" -version = "0.59.0" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.2", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.53.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - [[package]] name = "winnow" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -926,9 +801,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", @@ -959,9 +834,9 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -970,9 +845,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.2" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -981,9 +856,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", From e94fcd78a12f273e23f4c5d295c0a6053c3b0df2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Nov 2025 15:30:01 +0100 Subject: [PATCH 03/13] bump libloading --- src/tools/miri/Cargo.lock | 4 ++-- src/tools/miri/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index 84ccb28a26924..9c7cc020798b8 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -818,9 +818,9 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.9" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" dependencies = [ "cfg-if", "windows-link 0.2.1", diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 8bb4f1c160934..b10c68e40d845 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -40,7 +40,7 @@ features = ['unprefixed_malloc_on_supported_platforms'] libc = "0.2" # native-lib dependencies libffi = { version = "5.0.0", optional = true } -libloading = { version = "0.8", optional = true } +libloading = { version = "0.9", optional = true } serde = { version = "1.0.219", features = ["derive"], optional = true } [target.'cfg(target_os = "linux")'.dependencies] From 60ecc15a88ab9d36755824f95a9563399b994bf9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Nov 2025 15:31:26 +0100 Subject: [PATCH 04/13] bump cargo_metadata --- src/tools/miri/cargo-miri/Cargo.lock | 371 +-------------------------- src/tools/miri/cargo-miri/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 368 deletions(-) diff --git a/src/tools/miri/cargo-miri/Cargo.lock b/src/tools/miri/cargo-miri/Cargo.lock index 1f1c5ac50d3c8..45be05fcc7f78 100644 --- a/src/tools/miri/cargo-miri/Cargo.lock +++ b/src/tools/miri/cargo-miri/Cargo.lock @@ -8,12 +8,6 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - [[package]] name = "bitflags" version = "2.10.0" @@ -44,38 +38,21 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84982c6c0ae343635a3a4ee6dedef965513735c8b183caa7289fa6e27399ebd4" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-util-schemas" -version = "0.8.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc1a6f7b5651af85774ae5a34b4e8be397d9cf4bc063b7e6dbd99a841837830" +checksum = "122ec45a44b270afd1402f351b782c676b173e3c3fb28d86ff7ebfb4d86a4ee4" dependencies = [ - "semver", "serde", - "serde-untagged", - "serde-value", - "thiserror", - "toml", - "unicode-xid", - "url", ] [[package]] name = "cargo_metadata" -version = "0.21.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cfca2aaa699835ba88faf58a06342a314a950d2b9686165e038286c30316868" +checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" dependencies = [ "camino", "cargo-platform", - "cargo-util-schemas", "semver", "serde", "serde_json", @@ -109,34 +86,12 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" -[[package]] -name = "erased-serde" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" -dependencies = [ - "serde", - "serde_core", - "typeid", -] - [[package]] name = "errno" version = "0.3.14" @@ -153,15 +108,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - [[package]] name = "getrandom" version = "0.2.16" @@ -191,108 +137,6 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" -[[package]] -name = "icu_collections" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" - -[[package]] -name = "icu_properties" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" - -[[package]] -name = "icu_provider" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - [[package]] name = "indexmap" version = "2.12.0" @@ -331,27 +175,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" -[[package]] -name = "litemap" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" - [[package]] name = "memchr" version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -364,30 +193,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "ordered-float" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" -dependencies = [ - "num-traits", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "potential_utf" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" -dependencies = [ - "zerovec", -] - [[package]] name = "proc-macro2" version = "1.0.103" @@ -499,28 +304,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-untagged" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" -dependencies = [ - "erased-serde", - "serde", - "serde_core", - "typeid", -] - -[[package]] -name = "serde-value" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" -dependencies = [ - "ordered-float", - "serde", -] - [[package]] name = "serde_core" version = "1.0.228" @@ -563,18 +346,6 @@ dependencies = [ "serde", ] -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - [[package]] name = "syn" version = "2.0.110" @@ -586,17 +357,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "tempfile" version = "3.23.0" @@ -630,16 +390,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tinystr" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" -dependencies = [ - "displaydoc", - "zerovec", -] - [[package]] name = "toml" version = "0.8.23" @@ -682,42 +432,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" -[[package]] -name = "typeid" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" - [[package]] name = "unicode-ident" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "url" -version = "2.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - [[package]] name = "walkdir" version = "2.5.0" @@ -781,86 +501,3 @@ name = "wit-bindgen" version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "writeable" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - -[[package]] -name = "yoke" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerotrie" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/src/tools/miri/cargo-miri/Cargo.toml b/src/tools/miri/cargo-miri/Cargo.toml index 64b56ea114ecf..e8da7f2ca8a74 100644 --- a/src/tools/miri/cargo-miri/Cargo.toml +++ b/src/tools/miri/cargo-miri/Cargo.toml @@ -17,7 +17,7 @@ doctest = false # and no doc tests directories = "6" rustc_version = "0.4" serde_json = "1.0.40" -cargo_metadata = "0.21" +cargo_metadata = "0.23" rustc-build-sysroot = "0.5.10" # Enable some feature flags that dev-dependencies need but dependencies From 5df5103f990c95d445a426c431dfe6621ac3844d Mon Sep 17 00:00:00 2001 From: Michalis Kokologiannakis Date: Fri, 14 Nov 2025 19:47:33 +0100 Subject: [PATCH 05/13] genmc/build: Drop LLVM dependency from build GenMC (v0.14.1) no longer depends on LLVM when built as a library. This commit adjust genmc building and shim accordingly. --- src/tools/miri/genmc-sys/build.rs | 58 +------------------ .../genmc-sys/cpp/include/ResultHandling.hpp | 8 ++- 2 files changed, 6 insertions(+), 60 deletions(-) diff --git a/src/tools/miri/genmc-sys/build.rs b/src/tools/miri/genmc-sys/build.rs index 1b4e064d1ba21..d3f81fa1d7852 100644 --- a/src/tools/miri/genmc-sys/build.rs +++ b/src/tools/miri/genmc-sys/build.rs @@ -140,51 +140,6 @@ mod downloading { } } -// FIXME(genmc,llvm): Remove once the LLVM dependency of the GenMC model checker is removed. -/// The linked LLVM version is in the generated `config.h`` file, which we parse and use to link to LLVM. -/// Returns c++ compiler definitions required for building with/including LLVM, and the include path for LLVM headers. -fn link_to_llvm(config_file: &Path) -> (String, String) { - /// Search a string for a line matching `//@VARIABLE_NAME: VARIABLE CONTENT` - fn extract_value<'a>(input: &'a str, name: &str) -> Option<&'a str> { - input - .lines() - .find_map(|line| line.strip_prefix("//@")?.strip_prefix(name)?.strip_prefix(": ")) - } - - let file_content = std::fs::read_to_string(&config_file).unwrap_or_else(|err| { - panic!("GenMC config file ({}) should exist, but got errror {err:?}", config_file.display()) - }); - - let llvm_definitions = extract_value(&file_content, "LLVM_DEFINITIONS") - .expect("Config file should contain LLVM_DEFINITIONS"); - let llvm_include_dirs = extract_value(&file_content, "LLVM_INCLUDE_DIRS") - .expect("Config file should contain LLVM_INCLUDE_DIRS"); - let llvm_library_dir = extract_value(&file_content, "LLVM_LIBRARY_DIR") - .expect("Config file should contain LLVM_LIBRARY_DIR"); - let llvm_config_path = extract_value(&file_content, "LLVM_CONFIG_PATH") - .expect("Config file should contain LLVM_CONFIG_PATH"); - - // Add linker search path. - let lib_dir = PathBuf::from_str(llvm_library_dir).unwrap(); - println!("cargo::rustc-link-search=native={}", lib_dir.display()); - - // Add libraries to link. - let output = std::process::Command::new(llvm_config_path) - .arg("--libs") // Print the libraries to link to (space-separated list) - .output() - .expect("failed to execute llvm-config"); - let llvm_link_libs = - String::try_from(output.stdout).expect("llvm-config output should be a valid string"); - - for link_lib in llvm_link_libs.trim().split(" ") { - let link_lib = - link_lib.strip_prefix("-l").expect("Linker parameter should start with \"-l\""); - println!("cargo::rustc-link-lib=dylib={link_lib}"); - } - - (llvm_definitions.to_string(), llvm_include_dirs.to_string()) -} - /// Build the GenMC model checker library and the Rust-C++ interop library with cxx.rs fn compile_cpp_dependencies(genmc_path: &Path, always_configure: bool) { // Give each step a separate build directory to prevent interference. @@ -204,6 +159,7 @@ fn compile_cpp_dependencies(genmc_path: &Path, always_configure: bool) { .always_configure(always_configure) // We force running the configure step when the GenMC commit changed. .out_dir(genmc_build_dir) .profile(GENMC_CMAKE_PROFILE) + .define("BUILD_LLI", "OFF") .define("GENMC_DEBUG", if enable_genmc_debug { "ON" } else { "OFF" }); // The actual compilation happens here: @@ -214,19 +170,11 @@ fn compile_cpp_dependencies(genmc_path: &Path, always_configure: bool) { println!("cargo::rustc-link-search=native={}", cmake_lib_dir.display()); println!("cargo::rustc-link-lib=static={GENMC_MODEL_CHECKER}"); - // FIXME(genmc,llvm): Remove once the LLVM dependency of the GenMC model checker is removed. - let config_file = genmc_install_dir.join("include").join("genmc").join("config.h"); - let (llvm_definitions, llvm_include_dirs) = link_to_llvm(&config_file); - // Part 2: // Compile the cxx_bridge (the link between the Rust and C++ code). let genmc_include_dir = genmc_install_dir.join("include").join("genmc"); - // FIXME(genmc,llvm): remove once LLVM dependency is removed. - // These definitions are parsed into a cmake list and then printed to the config.h file, so they are ';' separated. - let definitions = llvm_definitions.split(";"); - // These are all the C++ files we need to compile, which needs to be updated if more C++ files are added to Miri. // We use absolute paths since relative paths can confuse IDEs when attempting to go-to-source on a path in a compiler error. let cpp_files_base_path = Path::new("cpp/src/"); @@ -244,16 +192,12 @@ fn compile_cpp_dependencies(genmc_path: &Path, always_configure: bool) { if enable_genmc_debug { bridge.define("ENABLE_GENMC_DEBUG", None); } - for definition in definitions { - bridge.flag(definition); - } bridge .opt_level(2) .debug(true) // Same settings that GenMC uses (default for cmake `RelWithDebInfo`) .warnings(false) // NOTE: enabling this produces a lot of warnings. .std("c++23") .include(genmc_include_dir) - .include(llvm_include_dirs) .include("./cpp/include") .files(&cpp_files) .out_dir(interface_build_dir) diff --git a/src/tools/miri/genmc-sys/cpp/include/ResultHandling.hpp b/src/tools/miri/genmc-sys/cpp/include/ResultHandling.hpp index 189f32e6f513d..cb5f49c179b05 100644 --- a/src/tools/miri/genmc-sys/cpp/include/ResultHandling.hpp +++ b/src/tools/miri/genmc-sys/cpp/include/ResultHandling.hpp @@ -7,14 +7,16 @@ // GenMC headers: #include "Verification/VerificationError.hpp" +#include +#include +#include #include /** Information about an error, formatted as a string to avoid having to share an error enum and * printing functionality with the Rust side. */ static auto format_error(VerificationError err) -> std::unique_ptr { - auto buf = std::string(); - auto s = llvm::raw_string_ostream(buf); - s << err; + std::stringstream s; + s << std::format("{}", err); return std::make_unique(s.str()); } From fbdf4aa3bbba21914f2029404513cfae7532a4c2 Mon Sep 17 00:00:00 2001 From: Michalis Kokologiannakis Date: Fri, 14 Nov 2025 20:15:10 +0100 Subject: [PATCH 06/13] genmc/setup: Check GenMC config validity GenMC v0.14.1 does not throw an error internally if the config is invalid, but rather returns an appropriate error value. This commit has setup code in Miri check the returned value, and exit if there are any errors. --- .../miri/genmc-sys/cpp/src/MiriInterface/Setup.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Setup.cpp b/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Setup.cpp index 5455b1a8de7f8..20c827221a92a 100644 --- a/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Setup.cpp +++ b/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Setup.cpp @@ -147,9 +147,16 @@ static auto to_genmc_verbosity_level(const LogLevel log_level) -> VerbosityLevel // that is allowed to leak and memory that is not. conf->warnUnfreedMemory = false; - // FIXME(genmc,error handling): This function currently exits on error, but will return an - // error value in the future. The return value should be checked once this change is made. - checkConfig(*conf); + // Validate the config and exit if there are any errors + std::vector warnings; + auto config_valid = conf->validate(warnings); + for (const auto& w : warnings) + WARN("{}", w); + if (auto* errors = std::get_if(&config_valid); errors) { + for (const auto& e : *errors) + LOG(VerbosityLevel::Error, "{}", e); + exit(EUSER); + } // Create the actual driver and Miri-GenMC communication shim. auto driver = std::make_unique(std::move(conf), mode); From b6cc543c3b35a34951329378b036afc92fe09d2b Mon Sep 17 00:00:00 2001 From: Michalis Kokologiannakis Date: Sat, 15 Nov 2025 17:09:14 +0100 Subject: [PATCH 07/13] genmc/api: Handle new GenMC error API The new error-reporting mechanism of GenMC changed its public API. This commit adjusts the Miri interface accordingly (all driver calls need an extra argument that represents possible debugging information). --- .../miri/genmc-sys/cpp/include/MiriInterface.hpp | 3 ++- .../genmc-sys/cpp/src/MiriInterface/EventHandling.cpp | 10 +++++++--- .../miri/genmc-sys/cpp/src/MiriInterface/Mutex.cpp | 4 ++++ .../cpp/src/MiriInterface/ThreadManagement.cpp | 11 ++++++----- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp b/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp index 3a04edc013681..4929c0cfa150f 100644 --- a/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp +++ b/src/tools/miri/genmc-sys/cpp/include/MiriInterface.hpp @@ -220,7 +220,8 @@ struct MiriGenmcShim : private GenMCDriver { auto handle_load_reset_if_none(ThreadId tid, std::optional old_val, Ts&&... params) -> HandleResult { const auto pos = inc_pos(tid); - const auto ret = GenMCDriver::handleLoad(pos, old_val, std::forward(params)...); + const auto ret = + GenMCDriver::handleLoad(nullptr, pos, old_val, std::forward(params)...); // If we didn't get a value, we have to reset the index of the current thread. if (!std::holds_alternative(ret)) { dec_pos(tid); diff --git a/src/tools/miri/genmc-sys/cpp/src/MiriInterface/EventHandling.cpp b/src/tools/miri/genmc-sys/cpp/src/MiriInterface/EventHandling.cpp index 2b6e5749d41a5..96fb803bcc4eb 100644 --- a/src/tools/miri/genmc-sys/cpp/src/MiriInterface/EventHandling.cpp +++ b/src/tools/miri/genmc-sys/cpp/src/MiriInterface/EventHandling.cpp @@ -34,7 +34,7 @@ void MiriGenmcShim::handle_assume_block(ThreadId thread_id, AssumeType assume_type) { BUG_ON(getExec().getGraph().isThreadBlocked(thread_id)); - GenMCDriver::handleAssume(inc_pos(thread_id), assume_type); + GenMCDriver::handleAssume(nullptr, inc_pos(thread_id), assume_type); } /**** Memory access handling ****/ @@ -76,6 +76,7 @@ void MiriGenmcShim::handle_assume_block(ThreadId thread_id, AssumeType assume_ty ) -> StoreResult { const auto pos = inc_pos(thread_id); const auto ret = GenMCDriver::handleStore( + nullptr, pos, GenmcScalarExt::try_to_sval(old_val), ord, @@ -100,7 +101,7 @@ void MiriGenmcShim::handle_assume_block(ThreadId thread_id, AssumeType assume_ty void MiriGenmcShim::handle_fence(ThreadId thread_id, MemOrdering ord) { const auto pos = inc_pos(thread_id); - GenMCDriver::handleFence(pos, ord, EventDeps()); + GenMCDriver::handleFence(nullptr, pos, ord, EventDeps()); } [[nodiscard]] auto MiriGenmcShim::handle_read_modify_write( @@ -143,6 +144,7 @@ void MiriGenmcShim::handle_fence(ThreadId thread_id, MemOrdering ord) { const auto storePos = inc_pos(thread_id); const auto store_ret = GenMCDriver::handleStore( + nullptr, storePos, GenmcScalarExt::try_to_sval(old_val), ordering, @@ -210,6 +212,7 @@ void MiriGenmcShim::handle_fence(ThreadId thread_id, MemOrdering ord) { const auto storePos = inc_pos(thread_id); const auto store_ret = GenMCDriver::handleStore( + nullptr, storePos, GenmcScalarExt::try_to_sval(old_val), success_ordering, @@ -242,6 +245,7 @@ auto MiriGenmcShim::handle_malloc(ThreadId thread_id, uint64_t size, uint64_t al const auto address_space = AddressSpace::AS_User; const SVal ret_val = GenMCDriver::handleMalloc( + nullptr, pos, size, alignment, @@ -255,7 +259,7 @@ auto MiriGenmcShim::handle_malloc(ThreadId thread_id, uint64_t size, uint64_t al auto MiriGenmcShim::handle_free(ThreadId thread_id, uint64_t address) -> bool { const auto pos = inc_pos(thread_id); - GenMCDriver::handleFree(pos, SAddr(address), EventDeps()); + GenMCDriver::handleFree(nullptr, pos, SAddr(address), EventDeps()); // FIXME(genmc): use returned error from `handleFree` once implemented in GenMC. return getResult().status.has_value(); } diff --git a/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Mutex.cpp b/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Mutex.cpp index fc3f5e6e09a67..af7e30186cbe0 100644 --- a/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Mutex.cpp +++ b/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Mutex.cpp @@ -60,6 +60,7 @@ auto MiriGenmcShim::handle_mutex_lock(ThreadId thread_id, uint64_t address, uint const bool is_lock_acquired = *ret_val == MUTEX_UNLOCKED; if (is_lock_acquired) { const auto store_ret = GenMCDriver::handleStore( + nullptr, inc_pos(thread_id), old_val, address, @@ -93,6 +94,7 @@ auto MiriGenmcShim::handle_mutex_try_lock(ThreadId thread_id, uint64_t address, // a mutex to be "unlocked". const auto old_val = MUTEX_UNLOCKED; const auto load_ret = GenMCDriver::handleLoad( + nullptr, ++currPos, old_val, SAddr(address), @@ -115,6 +117,7 @@ auto MiriGenmcShim::handle_mutex_try_lock(ThreadId thread_id, uint64_t address, } const auto store_ret = GenMCDriver::handleStore( + nullptr, ++currPos, old_val, SAddr(address), @@ -136,6 +139,7 @@ auto MiriGenmcShim::handle_mutex_unlock(ThreadId thread_id, uint64_t address, ui -> StoreResult { const auto pos = inc_pos(thread_id); const auto ret = GenMCDriver::handleStore( + nullptr, pos, // As usual, we need to tell GenMC which value was stored at this location before this // atomic access, if there previously was a non-atomic initializing access. We set the diff --git a/src/tools/miri/genmc-sys/cpp/src/MiriInterface/ThreadManagement.cpp b/src/tools/miri/genmc-sys/cpp/src/MiriInterface/ThreadManagement.cpp index d2061fcb406c9..85fc7d92f78f2 100644 --- a/src/tools/miri/genmc-sys/cpp/src/MiriInterface/ThreadManagement.cpp +++ b/src/tools/miri/genmc-sys/cpp/src/MiriInterface/ThreadManagement.cpp @@ -19,10 +19,11 @@ void MiriGenmcShim::handle_thread_create(ThreadId thread_id, ThreadId parent_id) // FIXME(genmc): for supporting symmetry reduction, these will need to be properly set: const unsigned fun_id = 0; const SVal arg = SVal(0); - const ThreadInfo child_info = ThreadInfo { thread_id, parent_id, fun_id, arg }; + const ThreadInfo child_info = + ThreadInfo { thread_id, parent_id, fun_id, arg, "unknown thread" }; // NOTE: Default memory ordering (`Release`) used here. - const auto child_tid = GenMCDriver::handleThreadCreate(pos, child_info, EventDeps()); + const auto child_tid = GenMCDriver::handleThreadCreate(nullptr, pos, child_info, EventDeps()); // Sanity check the thread id, which is the index in the `threads_action_` array. BUG_ON(child_tid != thread_id || child_tid <= 0 || child_tid != threads_action_.size()); threads_action_.push_back(Action(ActionKind::Load, Event(child_tid, 0))); @@ -33,7 +34,7 @@ void MiriGenmcShim::handle_thread_join(ThreadId thread_id, ThreadId child_id) { const auto pos = inc_pos(thread_id); // NOTE: Default memory ordering (`Acquire`) used here. - const auto ret = GenMCDriver::handleThreadJoin(pos, child_id, EventDeps()); + const auto ret = GenMCDriver::handleThreadJoin(nullptr, pos, child_id, EventDeps()); // If the join failed, decrease the event index again: if (!std::holds_alternative(ret)) { dec_pos(thread_id); @@ -46,10 +47,10 @@ void MiriGenmcShim::handle_thread_join(ThreadId thread_id, ThreadId child_id) { void MiriGenmcShim::handle_thread_finish(ThreadId thread_id, uint64_t ret_val) { const auto pos = inc_pos(thread_id); // NOTE: Default memory ordering (`Release`) used here. - GenMCDriver::handleThreadFinish(pos, SVal(ret_val)); + GenMCDriver::handleThreadFinish(nullptr, pos, SVal(ret_val)); } void MiriGenmcShim::handle_thread_kill(ThreadId thread_id) { const auto pos = inc_pos(thread_id); - GenMCDriver::handleThreadKill(pos); + GenMCDriver::handleThreadKill(nullptr, pos); } From 689358ab36d7f0f2b1ef4043fef2bae340eaffb6 Mon Sep 17 00:00:00 2001 From: Michalis Kokologiannakis Date: Sat, 15 Nov 2025 17:10:11 +0100 Subject: [PATCH 08/13] genmc/schedule: Handle new GenMC scheduling API When GenMC says that an execution should not be explored further, Miri needs to know why (e.g., so that it returns an appropriate exit value). Until now, some (erroneous) heuristics were used for that. This commit changes the Miri/GenMC API to check the scheduling result of GenMC (that now reflects the "stop type"). --- .../cpp/src/MiriInterface/Exploration.cpp | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Exploration.cpp b/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Exploration.cpp index 0f64083ddda68..7722c4bfab69e 100644 --- a/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Exploration.cpp +++ b/src/tools/miri/genmc-sys/cpp/src/MiriInterface/Exploration.cpp @@ -22,13 +22,23 @@ auto MiriGenmcShim::schedule_next( // a scheduling decision. threads_action_[curr_thread_id].kind = curr_thread_next_instr_kind; - if (const auto result = GenMCDriver::scheduleNext(threads_action_)) - return SchedulingResult { ExecutionState::Ok, static_cast(result.value()) }; - if (getExec().getGraph().isBlocked()) - return SchedulingResult { ExecutionState::Blocked, 0 }; - if (getResult().status.has_value()) // the "value" here is a `VerificationError` - return SchedulingResult { ExecutionState::Error, 0 }; - return SchedulingResult { ExecutionState::Finished, 0 }; + auto result = GenMCDriver::scheduleNext(threads_action_); + return std::visit( + [](auto&& arg) { + using T = std::decay_t; + if constexpr (std::is_same_v) + return SchedulingResult { ExecutionState::Ok, static_cast(arg) }; + else if constexpr (std::is_same_v) + return SchedulingResult { ExecutionState::Blocked, 0 }; + else if constexpr (std::is_same_v) + return SchedulingResult { ExecutionState::Error, 0 }; + else if constexpr (std::is_same_v) + return SchedulingResult { ExecutionState::Finished, 0 }; + else + static_assert(false, "non-exhaustive visitor!"); + }, + result + ); } /**** Execution start/end handling ****/ From 26bd44136097dd3f54c90c0657169111050736ef Mon Sep 17 00:00:00 2001 From: Michalis Kokologiannakis Date: Sun, 16 Nov 2025 18:29:30 +0100 Subject: [PATCH 09/13] genmc/build: Update GenMC version (v0.15.1) Now GenMC can be built as a standalone library, without LLVM dependencies. --- src/tools/miri/genmc-sys/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/genmc-sys/build.rs b/src/tools/miri/genmc-sys/build.rs index d3f81fa1d7852..9e956449a13df 100644 --- a/src/tools/miri/genmc-sys/build.rs +++ b/src/tools/miri/genmc-sys/build.rs @@ -28,7 +28,7 @@ mod downloading { /// The GenMC repository the we get our commit from. pub(crate) const GENMC_GITHUB_URL: &str = "https://github.com/MPI-SWS/genmc.git"; /// The GenMC commit we depend on. It must be available on the specified GenMC repository. - pub(crate) const GENMC_COMMIT: &str = "d9527280bb99f1cef64326b1803ffd952e3880df"; + pub(crate) const GENMC_COMMIT: &str = "aa10ed65117c3291524efc19253b5d443a4602ac"; /// Ensure that a local GenMC repo is present and set to the correct commit. /// Return the path of the GenMC repo and whether the checked out commit was changed. From 2f429f9f91ba3bad0ef6197c1038057a6bbd0fcc Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Mon, 17 Nov 2025 04:55:09 +0000 Subject: [PATCH 10/13] Prepare for merging from rust-lang/rust This updates the rust-version file to 69d4d5fc0e4db60272aac85ef27ecccef5764f3a. --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 06a5970646243..25bb5e923183c 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -7a72c5459dd58f81b0e1a0e5436d145485889375 +69d4d5fc0e4db60272aac85ef27ecccef5764f3a From cab7fac04f1219f22616ec801f79a1cc10b2109b Mon Sep 17 00:00:00 2001 From: Roy Ammerschuber Date: Mon, 13 Oct 2025 22:38:38 +0200 Subject: [PATCH 11/13] add basic wildcard provenance support to tree borrows --- src/tools/miri/Cargo.toml | 2 +- src/tools/miri/src/bin/miri.rs | 12 - src/tools/miri/src/borrow_tracker/mod.rs | 2 + .../borrow_tracker/stacked_borrows/stack.rs | 10 +- .../tree_borrows/diagnostics.rs | 53 +- .../src/borrow_tracker/tree_borrows/mod.rs | 44 +- .../src/borrow_tracker/tree_borrows/perms.rs | 46 ++ .../src/borrow_tracker/tree_borrows/tree.rs | 384 ++++++++++--- .../src/borrow_tracker/tree_borrows/unimap.rs | 21 +- .../borrow_tracker/tree_borrows/wildcard.rs | 519 ++++++++++++++++++ .../fail/tree_borrows/wildcard/dealloc.rs | 21 + .../fail/tree_borrows/wildcard/dealloc.stderr | 14 + .../tests/fail/tree_borrows/wildcard/gc.rs | 20 + .../fail/tree_borrows/wildcard/gc.stderr | 14 + .../wildcard/multi_exposed_child.rs | 64 +++ .../wildcard/multi_exposed_child.stderr | 25 + .../multi_exposed_child_unique_writer.rs | 47 ++ .../multi_exposed_child_unique_writer.stderr | 25 + .../multi_exposed_siblings_disable.rs | 38 ++ .../multi_exposed_siblings_disable.stderr | 14 + .../multi_exposed_siblings_foreign.rs | 38 ++ .../multi_exposed_siblings_foreign.stderr | 25 + .../wildcard/multi_exposed_siblings_local.rs | 50 ++ .../multi_exposed_siblings_local.stderr | 32 ++ .../multi_exposed_siblings_unique_writer.rs | 38 ++ ...ulti_exposed_siblings_unique_writer.stderr | 25 + .../wildcard/protector_conflicted.rs | 26 + .../wildcard/protector_conflicted.stderr | 21 + .../wildcard/single_exposed_disable.rs | 35 ++ .../wildcard/single_exposed_disable.stderr | 14 + .../wildcard/single_exposed_foreign.rs | 34 ++ .../wildcard/single_exposed_foreign.stderr | 25 + .../wildcard/single_exposed_local.rs | 22 + .../wildcard/single_exposed_local.stderr | 14 + .../wildcard/single_exposed_only_ro.rs | 11 + .../wildcard/single_exposed_only_ro.stderr | 14 + .../wildcard/strongly_protected_wildcard.rs | 15 + .../strongly_protected_wildcard.stderr | 42 ++ .../int-to-ptr.rs | 2 + .../issue-miri-2389.rs | 3 + .../stacked_borrows/issue-miri-2389.stderr | 12 - .../tree_borrows/wildcard/undetected_ub.rs | 145 +++++ .../pass/tree_borrows/wildcard/wildcard.rs | 171 ++++++ 43 files changed, 2037 insertions(+), 152 deletions(-) create mode 100644 src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/dealloc.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/dealloc.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/gc.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/gc.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_disable.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_disable.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_disable.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_disable.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_foreign.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_foreign.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_local.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_local.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_only_ro.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_only_ro.stderr create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs create mode 100644 src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr rename src/tools/miri/tests/pass/{stacked_borrows => both_borrows}/int-to-ptr.rs (97%) rename src/tools/miri/tests/pass/{stacked_borrows => both_borrows}/issue-miri-2389.rs (86%) delete mode 100644 src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.stderr create mode 100644 src/tools/miri/tests/pass/tree_borrows/wildcard/undetected_ub.rs create mode 100644 src/tools/miri/tests/pass/tree_borrows/wildcard/wildcard.rs diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 8bb4f1c160934..a2c2ad56ebd87 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -72,7 +72,7 @@ harness = false default = ["stack-cache", "native-lib"] genmc = ["dep:genmc-sys"] stack-cache = [] -stack-cache-consistency-check = ["stack-cache"] +expensive-consistency-checks = ["stack-cache"] tracing = ["serde_json"] native-lib = ["dep:libffi", "dep:libloading", "dep:capstone", "dep:ipc-channel", "dep:nix", "dep:serde"] diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 920fc29481916..83c2f028c89c2 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -513,7 +513,6 @@ fn main() { Some(BorrowTrackerMethod::TreeBorrows(TreeBorrowsParams { precise_interior_mut: true, })); - miri_config.provenance_mode = ProvenanceMode::Strict; } else if arg == "-Zmiri-tree-borrows-no-precise-interior-mut" { match &mut miri_config.borrow_tracker { Some(BorrowTrackerMethod::TreeBorrows(params)) => { @@ -711,17 +710,6 @@ fn main() { rustc_args.push(arg); } } - // Tree Borrows implies strict provenance, and is not compatible with native calls. - if matches!(miri_config.borrow_tracker, Some(BorrowTrackerMethod::TreeBorrows { .. })) { - if miri_config.provenance_mode != ProvenanceMode::Strict { - fatal_error!( - "Tree Borrows does not support integer-to-pointer casts, and hence requires strict provenance" - ); - } - if !miri_config.native_lib.is_empty() { - fatal_error!("Tree Borrows is not compatible with calling native functions"); - } - } // Native calls and strict provenance are not compatible. if !miri_config.native_lib.is_empty() && miri_config.provenance_mode == ProvenanceMode::Strict { diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index ebca7377fdbcc..66f60ae95892e 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -372,6 +372,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let borrow_tracker = this.machine.borrow_tracker.as_ref().unwrap(); // The body of this loop needs `borrow_tracker` immutably // so we can't move this code inside the following `end_call`. + for (alloc_id, tag) in &frame .extra .borrow_tracker @@ -398,6 +399,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } } borrow_tracker.borrow_mut().end_call(&frame.extra); + interp_ok(()) } } diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs index fcd6216fc32dc..d8eaba8ec2892 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs @@ -153,7 +153,7 @@ impl<'tcx> Stack { /// Panics if any of the caching mechanisms have broken, /// - The StackCache indices don't refer to the parallel items, /// - There are no Unique items outside of first_unique..last_unique - #[cfg(feature = "stack-cache-consistency-check")] + #[cfg(feature = "expensive-consistency-checks")] fn verify_cache_consistency(&self) { // Only a full cache needs to be valid. Also see the comments in find_granting_cache // and set_unknown_bottom. @@ -197,7 +197,7 @@ impl<'tcx> Stack { tag: ProvenanceExtra, exposed_tags: &FxHashSet, ) -> Result, ()> { - #[cfg(feature = "stack-cache-consistency-check")] + #[cfg(feature = "expensive-consistency-checks")] self.verify_cache_consistency(); let ProvenanceExtra::Concrete(tag) = tag else { @@ -334,7 +334,7 @@ impl<'tcx> Stack { // This primes the cache for the next access, which is almost always the just-added tag. self.cache.add(new_idx, new); - #[cfg(feature = "stack-cache-consistency-check")] + #[cfg(feature = "expensive-consistency-checks")] self.verify_cache_consistency(); } @@ -417,7 +417,7 @@ impl<'tcx> Stack { self.unique_range.end = self.unique_range.end.min(disable_start); } - #[cfg(feature = "stack-cache-consistency-check")] + #[cfg(feature = "expensive-consistency-checks")] self.verify_cache_consistency(); interp_ok(()) @@ -472,7 +472,7 @@ impl<'tcx> Stack { self.unique_range = 0..0; } - #[cfg(feature = "stack-cache-consistency-check")] + #[cfg(feature = "expensive-consistency-checks")] self.verify_cache_consistency(); interp_ok(()) } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs index f2410a08625dd..c454bb43a2f59 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs @@ -291,9 +291,10 @@ pub(super) struct TbError<'node> { pub conflicting_info: &'node NodeDebugInfo, // What kind of access caused this error (read, write, reborrow, deallocation) pub access_cause: AccessCause, - /// Which tag the access that caused this error was made through, i.e. + /// Which tag, if any, the access that caused this error was made through, i.e. /// which tag was used to read/write/deallocate. - pub accessed_info: &'node NodeDebugInfo, + /// Not set on wildcard accesses. + pub accessed_info: Option<&'node NodeDebugInfo>, } impl TbError<'_> { @@ -302,10 +303,20 @@ impl TbError<'_> { use TransitionError::*; let cause = self.access_cause; let accessed = self.accessed_info; + let accessed_str = + self.accessed_info.map(|v| format!("{v}")).unwrap_or_else(|| "".into()); let conflicting = self.conflicting_info; - let accessed_is_conflicting = accessed.tag == conflicting.tag; + // An access is considered conflicting if it happened through a + // different tag than the one who caused UB. + // When doing a wildcard access (where `accessed` is `None`) we + // do not know which precise tag the accessed happened from, + // however we can be certain that it did not come from the + // conflicting tag. + // This is because the wildcard data structure already removes + // all tags through which an access would cause UB. + let accessed_is_conflicting = accessed.map(|a| a.tag) == Some(conflicting.tag); let title = format!( - "{cause} through {accessed} at {alloc_id:?}[{offset:#x}] is forbidden", + "{cause} through {accessed_str} at {alloc_id:?}[{offset:#x}] is forbidden", alloc_id = self.alloc_id, offset = self.error_offset ); @@ -316,7 +327,7 @@ impl TbError<'_> { let mut details = Vec::new(); if !accessed_is_conflicting { details.push(format!( - "the accessed tag {accessed} is a child of the conflicting tag {conflicting}" + "the accessed tag {accessed_str} is a child of the conflicting tag {conflicting}" )); } let access = cause.print_as_access(/* is_foreign */ false); @@ -330,7 +341,7 @@ impl TbError<'_> { let access = cause.print_as_access(/* is_foreign */ true); let details = vec![ format!( - "the accessed tag {accessed} is foreign to the {conflicting_tag_name} tag {conflicting} (i.e., it is not a child)" + "the accessed tag {accessed_str} is foreign to the {conflicting_tag_name} tag {conflicting} (i.e., it is not a child)" ), format!( "this {access} would cause the {conflicting_tag_name} tag {conflicting} (currently {before_disabled}) to become Disabled" @@ -343,7 +354,7 @@ impl TbError<'_> { let conflicting_tag_name = "strongly protected"; let details = vec![ format!( - "the allocation of the accessed tag {accessed} also contains the {conflicting_tag_name} tag {conflicting}" + "the allocation of the accessed tag {accessed_str} also contains the {conflicting_tag_name} tag {conflicting}" ), format!("the {conflicting_tag_name} tag {conflicting} disallows deallocations"), ]; @@ -351,8 +362,10 @@ impl TbError<'_> { } }; let mut history = HistoryData::default(); - if !accessed_is_conflicting { - history.extend(self.accessed_info.history.forget(), "accessed", false); + if let Some(accessed_info) = self.accessed_info + && !accessed_is_conflicting + { + history.extend(accessed_info.history.forget(), "accessed", false); } history.extend( self.conflicting_info.history.extract_relevant(self.error_offset, self.error_kind), @@ -363,6 +376,20 @@ impl TbError<'_> { } } +/// Cannot access this allocation with wildcard provenance, as there are no +/// valid exposed references for this access kind. +pub fn no_valid_exposed_references_error<'tcx>( + alloc_id: AllocId, + offset: u64, + access_cause: AccessCause, +) -> InterpErrorKind<'tcx> { + let title = + format!("{access_cause} through at {alloc_id:?}[{offset:#x}] is forbidden"); + let details = vec![format!("there are no exposed tags which may perform this access here")]; + let history = HistoryData::default(); + err_machine_stop!(TerminationInfo::TreeBorrowsUb { title, details, history }) +} + type S = &'static str; /// Pretty-printing details /// @@ -623,10 +650,10 @@ impl DisplayRepr { } else { // We take this node let rperm = tree - .rperms + .locations .iter_all() - .map(move |(_offset, perms)| { - let perm = perms.get(idx); + .map(move |(_offset, loc)| { + let perm = loc.perms.get(idx); perm.cloned() }) .collect::>(); @@ -788,7 +815,7 @@ impl<'tcx> Tree { show_unnamed: bool, ) -> InterpResult<'tcx> { let mut indenter = DisplayIndent::new(); - let ranges = self.rperms.iter_all().map(|(range, _perms)| range).collect::>(); + let ranges = self.locations.iter_all().map(|(range, _loc)| range).collect::>(); if let Some(repr) = DisplayRepr::from(self, show_unnamed) { repr.print( &DEFAULT_FORMATTER, diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 720c5b239495e..f133edcba759c 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -14,6 +14,7 @@ mod foreign_access_skipping; mod perms; mod tree; mod unimap; +mod wildcard; #[cfg(test)] mod exhaustive; @@ -54,16 +55,10 @@ impl<'tcx> Tree { interpret::Pointer::new(alloc_id, range.start), range.size.bytes(), ); - // TODO: for now we bail out on wildcard pointers. Eventually we should - // handle them as much as we can. - let tag = match prov { - ProvenanceExtra::Concrete(tag) => tag, - ProvenanceExtra::Wildcard => return interp_ok(()), - }; let global = machine.borrow_tracker.as_ref().unwrap(); let span = machine.current_user_relevant_span(); self.perform_access( - tag, + prov, Some((range, access_kind, diagnostics::AccessCause::Explicit(access_kind))), global, alloc_id, @@ -79,19 +74,9 @@ impl<'tcx> Tree { size: Size, machine: &MiriMachine<'tcx>, ) -> InterpResult<'tcx> { - // TODO: for now we bail out on wildcard pointers. Eventually we should - // handle them as much as we can. - let tag = match prov { - ProvenanceExtra::Concrete(tag) => tag, - ProvenanceExtra::Wildcard => return interp_ok(()), - }; let global = machine.borrow_tracker.as_ref().unwrap(); let span = machine.current_user_relevant_span(); - self.dealloc(tag, alloc_range(Size::ZERO, size), global, alloc_id, span) - } - - pub fn expose_tag(&mut self, _tag: BorTag) { - // TODO + self.dealloc(prov, alloc_range(Size::ZERO, size), global, alloc_id, span) } /// A tag just lost its protector. @@ -109,7 +94,11 @@ impl<'tcx> Tree { ) -> InterpResult<'tcx> { let span = machine.current_user_relevant_span(); // `None` makes it the magic on-protector-end operation - self.perform_access(tag, None, global, alloc_id, span) + self.perform_access(ProvenanceExtra::Concrete(tag), None, global, alloc_id, span)?; + + self.update_exposure_for_protector_release(tag); + + interp_ok(()) } } @@ -239,21 +228,22 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { assert_eq!(ptr_size, Size::ZERO); // we did the deref check above, size has to be 0 here // This pointer doesn't come with an AllocId, so there's no // memory to do retagging in. + let new_prov = place.ptr().provenance; trace!( - "reborrow of size 0: reference {:?} derived from {:?} (pointee {})", - new_tag, + "reborrow of size 0: reusing {:?} (pointee {})", place.ptr(), place.layout.ty, ); log_creation(this, None)?; // Keep original provenance. - return interp_ok(place.ptr().provenance); + return interp_ok(new_prov); } }; + log_creation(this, Some((alloc_id, base_offset, parent_prov)))?; let orig_tag = match parent_prov { - ProvenanceExtra::Wildcard => return interp_ok(place.ptr().provenance), // TODO: handle wildcard pointers + ProvenanceExtra::Wildcard => return interp_ok(place.ptr().provenance), // TODO: handle retagging wildcard pointers ProvenanceExtra::Concrete(tag) => tag, }; @@ -356,7 +346,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> { }; tree_borrows.perform_access( - orig_tag, + parent_prov, Some((range_in_alloc, AccessKind::Read, diagnostics::AccessCause::Reborrow)), this.machine.borrow_tracker.as_ref().unwrap(), alloc_id, @@ -606,7 +596,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // uncovers a non-supported `extern static`. let alloc_extra = this.get_alloc_extra(alloc_id)?; trace!("Tree Borrows tag {tag:?} exposed in {alloc_id:?}"); - alloc_extra.borrow_tracker_tb().borrow_mut().expose_tag(tag); + + let global = this.machine.borrow_tracker.as_ref().unwrap(); + let protected_tags = &global.borrow().protected_tags; + let protected = protected_tags.contains_key(&tag); + alloc_extra.borrow_tracker_tb().borrow_mut().expose_tag(tag, protected); } AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => { // No tree borrows on these allocations. diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs index b84ebd51656c0..bd4573f94013e 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs @@ -53,6 +53,7 @@ enum PermissionPriv { } use self::PermissionPriv::*; use super::foreign_access_skipping::IdempotentForeignAccess; +use super::wildcard::WildcardAccessLevel; impl PartialOrd for PermissionPriv { /// PermissionPriv is ordered by the reflexive transitive closure of @@ -372,6 +373,23 @@ impl Permission { pub fn strongest_idempotent_foreign_access(&self, prot: bool) -> IdempotentForeignAccess { self.inner.strongest_idempotent_foreign_access(prot) } + + /// Returns the strongest access allowed from a child to this node without + /// causing UB (only considers possible transitions to this permission). + pub fn strongest_allowed_child_access(&self, protected: bool) -> WildcardAccessLevel { + match self.inner { + // Everything except disabled can be accessed by read access. + Disabled => WildcardAccessLevel::None, + // Frozen references cannot be written to by a child. + Frozen => WildcardAccessLevel::Read, + // If the `conflicted` flag is set, then there was a foreign read + // during the function call that is still ongoing (still `protected`), + // this is UB (`noalias` violation). + ReservedFrz { conflicted: true } if protected => WildcardAccessLevel::Read, + // Everything else allows writes. + _ => WildcardAccessLevel::Write, + } + } } impl PermTransition { @@ -772,4 +790,32 @@ mod propagation_optimization_checks { ); } } + + /// Checks that `strongest_allowed_child_access` correctly + /// represents which transitions are possible. + #[test] + fn strongest_allowed_child_access() { + for (permission, protected) in <(Permission, bool)>::exhaustive() { + let strongest_child_access = permission.strongest_allowed_child_access(protected); + + let is_read_valid = Permission::perform_access( + AccessKind::Read, + AccessRelatedness::LocalAccess, + permission, + protected, + ) + .is_some(); + + let is_write_valid = Permission::perform_access( + AccessKind::Write, + AccessRelatedness::LocalAccess, + permission, + protected, + ) + .is_some(); + + assert_eq!(is_read_valid, strongest_child_access >= WildcardAccessLevel::Read); + assert_eq!(is_write_valid, strongest_child_access >= WildcardAccessLevel::Write); + } + } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs index e337fe05e135d..7c30f76c29a1f 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs @@ -18,9 +18,11 @@ use rustc_data_structures::fx::FxHashSet; use rustc_span::Span; use smallvec::SmallVec; +use super::diagnostics::AccessCause; +use super::wildcard::WildcardState; use crate::borrow_tracker::tree_borrows::Permission; use crate::borrow_tracker::tree_borrows::diagnostics::{ - self, NodeDebugInfo, TbError, TransitionError, + self, NodeDebugInfo, TbError, TransitionError, no_valid_exposed_references_error, }; use crate::borrow_tracker::tree_borrows::foreign_access_skipping::IdempotentForeignAccess; use crate::borrow_tracker::tree_borrows::perms::PermTransition; @@ -30,7 +32,7 @@ use crate::*; mod tests; -/// Data for a single *location*. +/// Data for a reference at single *location*. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub(super) struct LocationState { /// A location is "accessed" when it is child-accessed for the first time (and the initial @@ -81,6 +83,49 @@ impl LocationState { self.permission } + /// Performs an access on this index and updates node, + /// perm and wildcard_state to reflect the transition. + fn perform_transition( + &mut self, + idx: UniIndex, + nodes: &mut UniValMap, + wildcard_accesses: &mut UniValMap, + access_kind: AccessKind, + access_cause: AccessCause, + access_range: Option, + relatedness: AccessRelatedness, + span: Span, + location_range: Range, + protected: bool, + ) -> Result<(), TransitionError> { + // Call this function now (i.e. only if we know `relatedness`), which + // ensures it is only called when `skip_if_known_noop` returns + // `Recurse`, due to the contract of `traverse_this_parents_children_other`. + self.record_new_access(access_kind, relatedness); + + let transition = self.perform_access(access_kind, relatedness, protected)?; + if !transition.is_noop() { + let node = nodes.get_mut(idx).unwrap(); + // Record the event as part of the history. + node.debug_info.history.push(diagnostics::Event { + transition, + is_foreign: relatedness.is_foreign(), + access_cause, + access_range, + transition_range: location_range, + span, + }); + + // We need to update the wildcard state, if the permission + // of an exposed pointer changes. + if node.is_exposed { + let access_type = self.permission.strongest_allowed_child_access(protected); + WildcardState::update_exposure(idx, access_type, nodes, wildcard_accesses); + } + } + Ok(()) + } + /// Apply the effect of an access to one location, including /// - applying `Permission::perform_access` to the inner `Permission`, /// - emitting protector UB if the location is accessed, @@ -211,30 +256,44 @@ impl fmt::Display for LocationState { Ok(()) } } - +/// The state of the full tree for a particular location: for all nodes, the local permissions +/// of that node, and the tracking for wildcard accesses. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct LocationTree { + /// Maps a tag to a perm, with possible lazy initialization. + /// + /// NOTE: not all tags registered in `Tree::nodes` are necessarily in all + /// ranges of `perms`, because `perms` is in part lazily initialized. + /// Just because `nodes.get(key)` is `Some(_)` does not mean you can safely + /// `unwrap` any `perm.get(key)`. + /// + /// We do uphold the fact that `keys(perms)` is a subset of `keys(nodes)` + pub perms: UniValMap, + /// Maps a tag and a location to its wildcard access tracking information, + /// with possible lazy initialization. + /// + /// If this allocation doesn't have any exposed nodes, then this map doesn't get + /// initialized. This way we only need to allocate the map if we need it. + /// + /// NOTE: same guarantees on entry initialization as for `perms`. + pub wildcard_accesses: UniValMap, +} /// Tree structure with both parents and children since we want to be /// able to traverse the tree efficiently in both directions. #[derive(Clone, Debug)] pub struct Tree { /// Mapping from tags to keys. The key obtained can then be used in - /// any of the `UniValMap` relative to this allocation, i.e. both the - /// `nodes` and `rperms` of the same `Tree`. + /// any of the `UniValMap` relative to this allocation, i.e. + /// `nodes`, `LocationTree::perms` and `LocationTree::wildcard_accesses` + /// of the same `Tree`. /// The parent-child relationship in `Node` is encoded in terms of these same /// keys, so traversing the entire tree needs exactly one access to /// `tag_mapping`. pub(super) tag_mapping: UniKeyMap, /// All nodes of this tree. pub(super) nodes: UniValMap, - /// Maps a tag and a location to a perm, with possible lazy - /// initialization. - /// - /// NOTE: not all tags registered in `nodes` are necessarily in all - /// ranges of `rperms`, because `rperms` is in part lazily initialized. - /// Just because `nodes.get(key)` is `Some(_)` does not mean you can safely - /// `unwrap` any `perm.get(key)`. - /// - /// We do uphold the fact that `keys(perms)` is a subset of `keys(nodes)` - pub(super) rperms: DedupRangeMap>, + /// Associates with each location its state and wildcard access tracking. + pub(super) locations: DedupRangeMap, /// The index of the root node. pub(super) root: UniIndex, } @@ -260,7 +319,9 @@ pub(super) struct Node { /// in cases where there is no location state yet. See `foreign_access_skipping.rs`, /// and `LocationState::idempotent_foreign_access` for more information default_initial_idempotent_foreign_access: IdempotentForeignAccess, - /// Some extra information useful only for debugging purposes + /// Whether a wildcard access could happen through this node. + pub is_exposed: bool, + /// Some extra information useful only for debugging purposes. pub debug_info: NodeDebugInfo, } @@ -273,7 +334,7 @@ struct NodeAppArgs<'visit> { /// The node map of this tree. nodes: &'visit mut UniValMap, /// The permissions map of this tree. - perms: &'visit mut UniValMap, + loc: &'visit mut LocationTree, } /// Data given to the error handler struct ErrHandlerArgs<'node, InErr> { @@ -293,7 +354,7 @@ struct ErrHandlerArgs<'node, InErr> { struct TreeVisitor<'tree> { tag_mapping: &'tree UniKeyMap, nodes: &'tree mut UniValMap, - perms: &'tree mut UniValMap, + loc: &'tree mut LocationTree, } /// Whether to continue exploring the children recursively or not. @@ -350,7 +411,7 @@ where idx: UniIndex, rel_pos: AccessRelatedness, ) -> ContinueTraversal { - let args = NodeAppArgs { idx, rel_pos, nodes: this.nodes, perms: this.perms }; + let args = NodeAppArgs { idx, rel_pos, nodes: this.nodes, loc: this.loc }; (self.f_continue)(&args) } @@ -360,14 +421,15 @@ where idx: UniIndex, rel_pos: AccessRelatedness, ) -> Result<(), OutErr> { - (self.f_propagate)(NodeAppArgs { idx, rel_pos, nodes: this.nodes, perms: this.perms }) - .map_err(|error_kind| { + (self.f_propagate)(NodeAppArgs { idx, rel_pos, nodes: this.nodes, loc: this.loc }).map_err( + |error_kind| { (self.err_builder)(ErrHandlerArgs { error_kind, conflicting_info: &this.nodes.get(idx).unwrap().debug_info, accessed_info: &this.nodes.get(self.initial).unwrap().debug_info, }) - }) + }, + ) } fn go_upwards_from_accessed( @@ -577,6 +639,7 @@ impl Tree { default_initial_perm: root_default_perm, // The root may never be skipped, all accesses will be local. default_initial_idempotent_foreign_access: IdempotentForeignAccess::None, + is_exposed: false, debug_info, }, ); @@ -595,9 +658,10 @@ impl Tree { IdempotentForeignAccess::None, ), ); - DedupRangeMap::new(size, perms) + let wildcard_accesses = UniValMap::default(); + DedupRangeMap::new(size, LocationTree { perms, wildcard_accesses }) }; - Self { root: root_idx, nodes, rperms, tag_mapping } + Self { root: root_idx, nodes, locations: rperms, tag_mapping } } } @@ -633,11 +697,13 @@ impl<'tcx> Tree { children: SmallVec::default(), default_initial_perm: outside_perm, default_initial_idempotent_foreign_access: default_strongest_idempotent, + is_exposed: false, debug_info: NodeDebugInfo::new(new_tag, outside_perm, span), }, ); + let parent_node = self.nodes.get_mut(parent_idx).unwrap(); // Register new_tag as a child of parent_tag - self.nodes.get_mut(parent_idx).unwrap().children.push(idx); + parent_node.children.push(idx); // We need to know the weakest SIFA for `update_idempotent_foreign_access_after_retag`. let mut min_sifa = default_strongest_idempotent; @@ -651,11 +717,19 @@ impl<'tcx> Tree { ); min_sifa = cmp::min(min_sifa, perm.idempotent_foreign_access); - for (_perms_range, perms) in self - .rperms + for (_range, loc) in self + .locations .iter_mut(Size::from_bytes(start) + base_offset, Size::from_bytes(end - start)) { - perms.insert(idx, perm); + loc.perms.insert(idx, perm); + } + } + + // We need to ensure the consistency of the wildcard access tracking data structure. + // For this, we insert the correct entry for this tag based on its parent, if it exists. + for (_range, loc) in self.locations.iter_mut_all() { + if let Some(parent_access) = loc.wildcard_accesses.get(parent_idx) { + loc.wildcard_accesses.insert(idx, parent_access.for_new_child()); } } @@ -689,9 +763,9 @@ impl<'tcx> Tree { // as the default SIFA for not-yet-initialized locations. // Record whether we did any change; if not, the invariant is restored and we can stop the traversal. let mut any_change = false; - for (_, map) in self.rperms.iter_mut_all() { + for (_range, loc) in self.locations.iter_mut_all() { // Check if this node has a state for this location (or range of locations). - if let Some(perm) = map.get_mut(current) { + if let Some(perm) = loc.perms.get_mut(current) { // Update the per-location SIFA, recording if it changed. any_change |= perm.idempotent_foreign_access.ensure_no_stronger_than(strongest_allowed); @@ -720,28 +794,37 @@ impl<'tcx> Tree { /// - the absence of Strong Protectors anywhere in the allocation pub fn dealloc( &mut self, - tag: BorTag, + prov: ProvenanceExtra, access_range: AllocRange, global: &GlobalState, alloc_id: AllocId, // diagnostics span: Span, // diagnostics ) -> InterpResult<'tcx> { self.perform_access( - tag, + prov, Some((access_range, AccessKind::Write, diagnostics::AccessCause::Dealloc)), global, alloc_id, span, )?; - for (perms_range, perms) in self.rperms.iter_mut(access_range.start, access_range.size) { - TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } + + // Check if this breaks any strong protector. + // (Weak protectors are already handled by `perform_access`.) + for (loc_range, loc) in self.locations.iter_mut(access_range.start, access_range.size) { + // The order in which we check if any nodes are invalidated only + // matters to diagnostics, so we use the root as a default tag. + let start_tag = match prov { + ProvenanceExtra::Concrete(tag) => tag, + ProvenanceExtra::Wildcard => self.nodes.get(self.root).unwrap().tag, + }; + TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, loc } .traverse_this_parents_children_other( - tag, - // visit all children, skipping none + start_tag, + // Visit all children, skipping none. |_| ContinueTraversal::Recurse, |args: NodeAppArgs<'_>| -> Result<(), TransitionError> { let node = args.nodes.get(args.idx).unwrap(); - let perm = args.perms.entry(args.idx); + let perm = args.loc.perms.entry(args.idx); let perm = perm.get().copied().unwrap_or_else(|| node.default_location_state()); @@ -764,9 +847,15 @@ impl<'tcx> Tree { conflicting_info, access_cause: diagnostics::AccessCause::Dealloc, alloc_id, - error_offset: perms_range.start, + error_offset: loc_range.start, error_kind, - accessed_info, + accessed_info: match prov { + ProvenanceExtra::Concrete(_) => Some(accessed_info), + // `accessed_info` contains the info of `start_tag`. + // On a wildcard access this is not the info of the accessed tag + // (as we don't know the accessed tag). + ProvenanceExtra::Wildcard => None, + }, } .build() }, @@ -795,12 +884,15 @@ impl<'tcx> Tree { /// - recording the history. pub fn perform_access( &mut self, - tag: BorTag, + prov: ProvenanceExtra, access_range_and_kind: Option<(AllocRange, AccessKind, diagnostics::AccessCause)>, global: &GlobalState, alloc_id: AllocId, // diagnostics span: Span, // diagnostics ) -> InterpResult<'tcx> { + let ProvenanceExtra::Concrete(tag) = prov else { + return self.perform_wildcard_access(access_range_and_kind, global, alloc_id, span); + }; use std::ops::Range; // Performs the per-node work: // - insert the permission if it does not exist @@ -814,7 +906,7 @@ impl<'tcx> Tree { // the `RangeMap` on which we are currently working). let node_skipper = |access_kind: AccessKind, args: &NodeAppArgs<'_>| -> ContinueTraversal { let node = args.nodes.get(args.idx).unwrap(); - let perm = args.perms.get(args.idx); + let perm = args.loc.perms.get(args.idx); let old_state = perm.copied().unwrap_or_else(|| node.default_location_state()); old_state.skip_if_known_noop(access_kind, args.rel_pos) @@ -825,29 +917,23 @@ impl<'tcx> Tree { args: NodeAppArgs<'_>| -> Result<(), TransitionError> { let node = args.nodes.get_mut(args.idx).unwrap(); - let mut perm = args.perms.entry(args.idx); - - let old_state = perm.or_insert(node.default_location_state()); + let mut perm = args.loc.perms.entry(args.idx); - // Call this function now, which ensures it is only called when - // `skip_if_known_noop` returns `Recurse`, due to the contract of - // `traverse_this_parents_children_other`. - old_state.record_new_access(access_kind, args.rel_pos); + let state = perm.or_insert(node.default_location_state()); let protected = global.borrow().protected_tags.contains_key(&node.tag); - let transition = old_state.perform_access(access_kind, args.rel_pos, protected)?; - // Record the event as part of the history - if !transition.is_noop() { - node.debug_info.history.push(diagnostics::Event { - transition, - is_foreign: args.rel_pos.is_foreign(), - access_cause, - access_range: access_range_and_kind.map(|x| x.0), - transition_range: perms_range, - span, - }); - } - Ok(()) + state.perform_transition( + args.idx, + args.nodes, + &mut args.loc.wildcard_accesses, + access_kind, + access_cause, + /* access_range */ access_range_and_kind.map(|x| x.0), + args.rel_pos, + span, + perms_range, + protected, + ) }; // Error handler in case `node_app` goes wrong. @@ -863,7 +949,7 @@ impl<'tcx> Tree { alloc_id, error_offset: perms_range.start, error_kind, - accessed_info, + accessed_info: Some(accessed_info), } .build() }; @@ -871,14 +957,13 @@ impl<'tcx> Tree { if let Some((access_range, access_kind, access_cause)) = access_range_and_kind { // Default branch: this is a "normal" access through a known range. // We iterate over affected locations and traverse the tree for each of them. - for (perms_range, perms) in self.rperms.iter_mut(access_range.start, access_range.size) - { - TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } + for (loc_range, loc) in self.locations.iter_mut(access_range.start, access_range.size) { + TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, loc } .traverse_this_parents_children_other( tag, |args| node_skipper(access_kind, args), - |args| node_app(perms_range.clone(), access_kind, access_cause, args), - |args| err_handler(perms_range.clone(), access_cause, args), + |args| node_app(loc_range.clone(), access_kind, access_cause, args), + |args| err_handler(loc_range.clone(), access_cause, args), )?; } } else { @@ -891,21 +976,21 @@ impl<'tcx> Tree { // See the test case `returned_mut_is_usable` from // `tests/pass/tree_borrows/tree-borrows.rs` for an example of // why this is important. - for (perms_range, perms) in self.rperms.iter_mut_all() { + for (loc_range, loc) in self.locations.iter_mut_all() { let idx = self.tag_mapping.get(&tag).unwrap(); // Only visit accessed permissions - if let Some(p) = perms.get(idx) + if let Some(p) = loc.perms.get(idx) && let Some(access_kind) = p.permission.protector_end_access() && p.accessed { let access_cause = diagnostics::AccessCause::FnExit(access_kind); - TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, perms } + TreeVisitor { nodes: &mut self.nodes, tag_mapping: &self.tag_mapping, loc } .traverse_nonchildren( - tag, - |args| node_skipper(access_kind, args), - |args| node_app(perms_range.clone(), access_kind, access_cause, args), - |args| err_handler(perms_range.clone(), access_cause, args), - )?; + tag, + |args| node_skipper(access_kind, args), + |args| node_app(loc_range.clone(), access_kind, access_cause, args), + |args| err_handler(loc_range.clone(), access_cause, args), + )?; } } } @@ -921,7 +1006,7 @@ impl Tree { // merge some adjacent ranges that were made equal by the removal of some // tags (this does not necessarily mean that they have identical internal representations, // see the `PartialEq` impl for `UniValMap`) - self.rperms.merge_adjacent_thorough(); + self.locations.merge_adjacent_thorough(); } /// Checks if a node is useless and should be GC'ed. @@ -953,10 +1038,14 @@ impl Tree { let child = self.nodes.get(child_idx).unwrap(); // Check that for that one child, `can_be_replaced_by_child` holds for the permission // on all locations. - for (_, data) in self.rperms.iter_all() { - let parent_perm = - data.get(idx).map(|x| x.permission).unwrap_or_else(|| node.default_initial_perm); - let child_perm = data + for (_range, loc) in self.locations.iter_all() { + let parent_perm = loc + .perms + .get(idx) + .map(|x| x.permission) + .unwrap_or_else(|| node.default_initial_perm); + let child_perm = loc + .perms .get(child_idx) .map(|x| x.permission) .unwrap_or_else(|| child.default_initial_perm); @@ -980,8 +1069,9 @@ impl Tree { // before we can safely apply `UniKeyMap::remove` to truly remove // this tag from the `tag_mapping`. let node = self.nodes.remove(this).unwrap(); - for (_perms_range, perms) in self.rperms.iter_mut_all() { - perms.remove(this); + for (_range, loc) in self.locations.iter_mut_all() { + loc.perms.remove(this); + loc.wildcard_accesses.remove(this); } self.tag_mapping.remove(&node.tag); } @@ -1058,6 +1148,126 @@ impl Tree { } } +/// Methods for wildcard accesses. +impl<'tcx> Tree { + /// Analogous to `perform_access`, but we do not know from which exposed + /// reference the access happens. + pub fn perform_wildcard_access( + &mut self, + access_range_and_kind: Option<(AllocRange, AccessKind, diagnostics::AccessCause)>, + global: &GlobalState, + alloc_id: AllocId, // diagnostics + span: Span, // diagnostics + ) -> InterpResult<'tcx> { + #[cfg(feature = "expensive-consistency-checks")] + self.verify_wildcard_consistency(global); + + if let Some((access_range, access_kind, access_cause)) = access_range_and_kind { + // This does a traversal starting from the root through the tree updating + // the permissions of each node. + // The difference to `perform_access` is that we take the access + // relatedness from the wildcard tracking state of the node instead of + // from the visitor itself. + for (loc_range, loc) in self.locations.iter_mut(access_range.start, access_range.size) { + let root_tag = self.nodes.get(self.root).unwrap().tag; + TreeVisitor { loc, nodes: &mut self.nodes, tag_mapping: &self.tag_mapping } + .traverse_this_parents_children_other( + root_tag, + |args: &NodeAppArgs<'_>| -> ContinueTraversal { + let node = args.nodes.get(args.idx).unwrap(); + let perm = args.loc.perms.get(args.idx); + let wildcard_state = args + .loc + .wildcard_accesses + .get(args.idx) + .cloned() + .unwrap_or_default(); + + let old_state = + perm.copied().unwrap_or_else(|| node.default_location_state()); + // If we know where, relative to this node, the wildcard access occurs, + // then check if we can skip the entire subtree. + if let Some(relatedness) = + wildcard_state.access_relatedness(access_kind) + && let Some(relatedness) = relatedness.to_relatedness() + { + // We can use the usual SIFA machinery to skip nodes. + old_state.skip_if_known_noop(access_kind, relatedness) + } else { + ContinueTraversal::Recurse + } + }, + |args| { + let node = args.nodes.get_mut(args.idx).unwrap(); + let mut entry = args.loc.perms.entry(args.idx); + let perm = entry.or_insert(node.default_location_state()); + + let protected = global.borrow().protected_tags.contains_key(&node.tag); + + let Some(wildcard_relatedness) = args + .loc + .wildcard_accesses + .get(args.idx) + .and_then(|s| s.access_relatedness(access_kind)) + else { + // There doesn't exist a valid exposed reference for this access to + // happen through. + // If this fails for one id, then it fails for all ids so this. + // Since we always check the root first, this means it should always + // fail on the root. + assert_eq!(self.root, args.idx); + return Err(no_valid_exposed_references_error( + alloc_id, + loc_range.start, + access_cause, + )); + }; + + let Some(relatedness) = wildcard_relatedness.to_relatedness() else { + // If the access type is Either, then we do not apply any transition + // to this node, but we still update each of its children. + // This is an imprecision! In the future, maybe we can still do some sort + // of best-effort update here. + return Ok(()); + }; + // We know the exact relatedness, so we can actually do precise checks. + perm.perform_transition( + args.idx, + args.nodes, + &mut args.loc.wildcard_accesses, + access_kind, + access_cause, + Some(access_range), + relatedness, + span, + loc_range.clone(), + protected, + ) + .map_err(|trans| { + let node = args.nodes.get(args.idx).unwrap(); + TbError { + conflicting_info: &node.debug_info, + access_cause, + alloc_id, + error_offset: loc_range.start, + error_kind: trans, + accessed_info: None, + } + .build() + }) + }, + |err| err.error_kind, + )?; + } + } else { + // This is for the special access when a protector gets released. + // Wildcard pointers are never protected, so this is unreachable. + unreachable!() + }; + interp_ok(()) + } +} + impl Node { pub fn default_location_state(&self) -> LocationState { LocationState::new_non_accessed( @@ -1071,7 +1281,15 @@ impl VisitProvenance for Tree { fn visit_provenance(&self, visit: &mut VisitWith<'_>) { // To ensure that the root never gets removed, we visit it // (the `root` node of `Tree` is not an `Option<_>`) - visit(None, Some(self.nodes.get(self.root).unwrap().tag)) + visit(None, Some(self.nodes.get(self.root).unwrap().tag)); + + // We also need to keep around any exposed tags through which + // an access could still happen. + for (_id, node) in self.nodes.iter() { + if node.is_exposed { + visit(None, Some(node.tag)) + } + } } } diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs index ad0a565dfd857..6400a62f444f0 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/unimap.rs @@ -12,6 +12,7 @@ #![allow(dead_code)] +use std::fmt::Debug; use std::hash::Hash; use std::mem; @@ -20,10 +21,15 @@ use rustc_data_structures::fx::FxHashMap; use crate::helpers::ToUsize; /// Intermediate key between a UniKeyMap and a UniValMap. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, PartialEq, Eq)] pub struct UniIndex { idx: u32, } +impl Debug for UniIndex { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.idx.fmt(f) + } +} /// From K to UniIndex #[derive(Debug, Clone, Default)] @@ -201,6 +207,19 @@ impl UniValMap { mem::swap(&mut res, &mut self.data[idx.idx.to_usize()]); res } + + /// Returns true if the map is empty. + pub fn is_empty(&self) -> bool { + self.data.iter().all(|v| v.is_none()) + } + + /// Iterates over all key-value pairs in the map. + pub fn iter(&self) -> impl Iterator { + self.data + .iter() + .enumerate() + .filter_map(|(i, v)| v.as_ref().map(|r| (UniIndex { idx: i.try_into().unwrap() }, r))) + } } /// An access to a single value of the map. diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs new file mode 100644 index 0000000000000..56a85e6f4ced3 --- /dev/null +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/wildcard.rs @@ -0,0 +1,519 @@ +use std::cmp::max; +use std::fmt::Debug; + +use super::Tree; +use super::tree::{AccessRelatedness, Node}; +use super::unimap::{UniIndex, UniValMap}; +use crate::BorTag; +use crate::borrow_tracker::AccessKind; +#[cfg(feature = "expensive-consistency-checks")] +use crate::borrow_tracker::GlobalState; + +/// Represents the maximum access level that is possible. +/// +/// Note that we derive Ord and PartialOrd, so the order in which variants are listed below matters: +/// None < Read < Write. Do not change that order. +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] +pub enum WildcardAccessLevel { + #[default] + None, + Read, + Write, +} + +/// Where the access happened relative to the current node. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum WildcardAccessRelatedness { + /// The access definitively happened through a local node. + LocalAccess, + /// The access definitively happened through a foreign node. + ForeignAccess, + /// We do not know if the access is foreign or local. + EitherAccess, +} +impl WildcardAccessRelatedness { + pub fn to_relatedness(self) -> Option { + match self { + Self::LocalAccess => Some(AccessRelatedness::LocalAccess), + Self::ForeignAccess => Some(AccessRelatedness::ForeignAccess), + Self::EitherAccess => None, + } + } +} + +/// State per location per node keeping track of where relative to this +/// node exposed nodes are and what access permissions they have. +/// +/// Designed to be completely determined by its parent, siblings and +/// direct children's max_local_access/max_foreign_access. +#[derive(Clone, Default, PartialEq, Eq)] +pub struct WildcardState { + /// How many of this node's direct children have `max_local_access()==Write`. + child_writes: u16, + /// How many of this node's direct children have `max_local_access()>=Read`. + child_reads: u16, + /// The maximum access level that could happen from an exposed node + /// that is foreign to this node. + /// + /// This is calculated as the `max()` of the parent's `max_foreign_access`, + /// `exposed_as` and the siblings' `max_local_access()`. + max_foreign_access: WildcardAccessLevel, + /// At what access level this node itself is exposed. + exposed_as: WildcardAccessLevel, +} +impl Debug for WildcardState { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("WildcardState") + .field("child_r/w", &(self.child_reads, self.child_writes)) + .field("foreign", &self.max_foreign_access) + .field("exposed_as", &self.exposed_as) + .finish() + } +} +impl WildcardState { + /// The maximum access level that could happen from an exposed + /// node that is local to this node. + fn max_local_access(&self) -> WildcardAccessLevel { + use WildcardAccessLevel::*; + max( + self.exposed_as, + if self.child_writes > 0 { + Write + } else if self.child_reads > 0 { + Read + } else { + None + }, + ) + } + + /// From where relative to the node with this wildcard info a read or write access could happen. + pub fn access_relatedness(&self, kind: AccessKind) -> Option { + match kind { + AccessKind::Read => self.read_access_relatedness(), + AccessKind::Write => self.write_access_relatedness(), + } + } + + /// From where relative to the node with this wildcard info a read access could happen. + fn read_access_relatedness(&self) -> Option { + let has_foreign = self.max_foreign_access >= WildcardAccessLevel::Read; + let has_local = self.max_local_access() >= WildcardAccessLevel::Read; + use WildcardAccessRelatedness as E; + match (has_foreign, has_local) { + (true, true) => Some(E::EitherAccess), + (true, false) => Some(E::ForeignAccess), + (false, true) => Some(E::LocalAccess), + (false, false) => None, + } + } + + /// From where relative to the node with this wildcard info a write access could happen. + fn write_access_relatedness(&self) -> Option { + let has_foreign = self.max_foreign_access == WildcardAccessLevel::Write; + let has_local = self.max_local_access() == WildcardAccessLevel::Write; + use WildcardAccessRelatedness as E; + match (has_foreign, has_local) { + (true, true) => Some(E::EitherAccess), + (true, false) => Some(E::ForeignAccess), + (false, true) => Some(E::LocalAccess), + (false, false) => None, + } + } + + /// Gets the access tracking information for a new child node of a parent with this + /// wildcard info. + /// The new node doesn't have any child reads/writes, but calculates `max_foreign_access` + /// from its parent. + pub fn for_new_child(&self) -> Self { + Self { + max_foreign_access: max(self.max_foreign_access, self.max_local_access()), + ..Default::default() + } + } + + /// Pushes the nodes of `children` onto the stack who's `max_foreign_access` + /// needs to be updated. + /// + /// * `children`: A list of nodes with the same parent. `children` doesn't + /// necessarily have to contain all children of parent, but can just be + /// a subset. + /// + /// * `child_reads`, `child_writes`: How many of `children` have `max_local_access()` + /// of at least `read`/`write` + /// + /// * `new_foreign_access`, `old_foreign_access`: + /// The max possible access level that is foreign to all `children` + /// (i.e., it is not local to *any* of them). + /// This can be calculated as the max of the parent's `exposed_as()`, `max_foreign_access` + /// and of all `max_local_access()` of any nodes with the same parent that are + /// not listed in `children`. + /// + /// This access level changed from `old` to `new`, which is why we need to + /// update `children`. + fn push_relevant_children( + stack: &mut Vec<(UniIndex, WildcardAccessLevel)>, + new_foreign_access: WildcardAccessLevel, + old_foreign_access: WildcardAccessLevel, + child_reads: u16, + child_writes: u16, + children: impl Iterator, + + wildcard_accesses: &UniValMap, + ) { + use WildcardAccessLevel::*; + + // Nothing changed so we don't need to update anything. + if new_foreign_access == old_foreign_access { + return; + } + + // We need to consider that the children's `max_local_access()` affect each + // other's `max_foreign_access`, but do not affect their own `max_foreign_access`. + + // The new `max_foreign_acces` for children with `max_local_access()==Write`. + let write_foreign_access = max( + new_foreign_access, + if child_writes > 1 { + // There exists at least one more child with exposed write access. + // This means that a foreign write through that node is possible. + Write + } else if child_reads > 1 { + // There exists at least one more child with exposed read access, + // but no other with write access. + // This means that a foreign read but no write through that node + // is possible. + Read + } else { + // There are no other nodes with read or write access. + // This means no foreign writes through other children are possible. + None + }, + ); + + // The new `max_foreign_acces` for children with `max_local_access()==Read`. + let read_foreign_access = max( + new_foreign_access, + if child_writes > 0 { + // There exists at least one child with write access (and it's not this one). + Write + } else if child_reads > 1 { + // There exists at least one more child with exposed read access, + // but no other with write access. + Read + } else { + // There are no other nodes with read or write access, + None + }, + ); + + // The new `max_foreign_acces` for children with `max_local_access()==None`. + let none_foreign_access = max( + new_foreign_access, + if child_writes > 0 { + // There exists at least one child with write access (and it's not this one). + Write + } else if child_reads > 0 { + // There exists at least one child with read access (and it's not this one), + // but none with write access. + Read + } else { + // No children are exposed as read or write. + None + }, + ); + + stack.extend(children.filter_map(|child| { + let state = wildcard_accesses.get(child).cloned().unwrap_or_default(); + + let new_foreign_access = match state.max_local_access() { + Write => write_foreign_access, + Read => read_foreign_access, + None => none_foreign_access, + }; + + if new_foreign_access != state.max_foreign_access { + Some((child, new_foreign_access)) + } else { + Option::None + } + })); + } + + /// Update the tracking information of a tree, to reflect that the node specified by `id` is + /// now exposed with `new_exposed_as`. + /// + /// Propagates the Willard access information over the tree. This needs to be called every + /// time the access level of an exposed node changes, to keep the state in sync with + /// the rest of the tree. + pub fn update_exposure( + id: UniIndex, + new_exposed_as: WildcardAccessLevel, + nodes: &UniValMap, + wildcard_accesses: &mut UniValMap, + ) { + let mut entry = wildcard_accesses.entry(id); + let src_state = entry.or_insert(Default::default()); + let old_exposed_as = src_state.exposed_as; + + // If the exposure doesn't change, then we don't need to update anything. + if old_exposed_as == new_exposed_as { + return; + } + + let src_old_local_access = src_state.max_local_access(); + + src_state.exposed_as = new_exposed_as; + + let src_new_local_access = src_state.max_local_access(); + + // Stack of nodes for which the max_foreign_access field needs to be updated. + // Will be filled with the children of this node and its parents children before + // we begin downwards traversal. + let mut stack: Vec<(UniIndex, WildcardAccessLevel)> = Vec::new(); + + // Add the direct children of this node to the stack. + { + let node = nodes.get(id).unwrap(); + Self::push_relevant_children( + &mut stack, + // new_foreign_access + max(src_state.max_foreign_access, new_exposed_as), + // old_foreign_access + max(src_state.max_foreign_access, old_exposed_as), + // Consider all children. + src_state.child_reads, + src_state.child_writes, + node.children.iter().copied(), + wildcard_accesses, + ); + } + // We need to propagate the tracking info up the tree, for this we traverse + // up the parents. + // We can skip propagating info to the parent and siblings of a node if its + // access didn't change. + { + // The child from which we came. + let mut child = id; + // This is the `max_local_access()` of the child we came from, before + // this update... + let mut old_child_access = src_old_local_access; + // and after this update. + let mut new_child_access = src_new_local_access; + while let Some(parent_id) = nodes.get(child).unwrap().parent { + let parent_node = nodes.get(parent_id).unwrap(); + let mut entry = wildcard_accesses.entry(parent_id); + let parent_state = entry.or_insert(Default::default()); + + let old_parent_local_access = parent_state.max_local_access(); + use WildcardAccessLevel::*; + // Updating this node's tracking state for its children. + match (old_child_access, new_child_access) { + (None | Read, Write) => parent_state.child_writes += 1, + (Write, None | Read) => parent_state.child_writes -= 1, + _ => {} + } + match (old_child_access, new_child_access) { + (None, Read | Write) => parent_state.child_reads += 1, + (Read | Write, None) => parent_state.child_reads -= 1, + _ => {} + } + + let new_parent_local_access = parent_state.max_local_access(); + + { + // We need to update the `max_foreign_access` of `child`'s + // siblings. For this we can reuse the `push_relevant_children` + // function. + // + // We pass it just the siblings without child itself. Since + // `child`'s `max_local_access()` is foreign to all of its + // siblings we can pass it as part of the foreign access. + + let parent_access = + max(parent_state.exposed_as, parent_state.max_foreign_access); + // This is how many of `child`'s siblings have read/write local access. + // If `child` itself has access, then we need to subtract its access from the count. + let sibling_reads = + parent_state.child_reads - if new_child_access >= Read { 1 } else { 0 }; + let sibling_writes = + parent_state.child_writes - if new_child_access >= Write { 1 } else { 0 }; + Self::push_relevant_children( + &mut stack, + // new_foreign_access + max(parent_access, new_child_access), + // old_foreign_access + max(parent_access, old_child_access), + // Consider only siblings of child. + sibling_reads, + sibling_writes, + parent_node.children.iter().copied().filter(|id| child != *id), + wildcard_accesses, + ); + } + if old_parent_local_access == new_parent_local_access { + // We didn't change `max_local_access()` for parent, so we don't need to propagate further upwards. + break; + } + + old_child_access = old_parent_local_access; + new_child_access = new_parent_local_access; + child = parent_id; + } + } + // Traverses down the tree to update max_foreign_access fields of children and cousins who need to be updated. + while let Some((id, new_access)) = stack.pop() { + let node = nodes.get(id).unwrap(); + let mut entry = wildcard_accesses.entry(id); + let state = entry.or_insert(Default::default()); + + let old_access = state.max_foreign_access; + state.max_foreign_access = new_access; + + Self::push_relevant_children( + &mut stack, + // new_foreign_access + max(state.exposed_as, new_access), + // old_foreign_access + max(state.exposed_as, old_access), + // Consider all children. + state.child_reads, + state.child_writes, + node.children.iter().copied(), + wildcard_accesses, + ); + } + } +} + +impl Tree { + /// Marks the tag as exposed & updates the wildcard tracking data structure + /// to represent its access level. + /// Also takes as an argument whether the tag is protected or not. + pub fn expose_tag(&mut self, tag: BorTag, protected: bool) { + let id = self.tag_mapping.get(&tag).unwrap(); + let node = self.nodes.get_mut(id).unwrap(); + node.is_exposed = true; + let node = self.nodes.get(id).unwrap(); + + // When the first tag gets exposed then we initialize the + // wildcard state for every node and location in the tree. + for (_, loc) in self.locations.iter_mut_all() { + let perm = loc + .perms + .get(id) + .map(|p| p.permission()) + .unwrap_or_else(|| node.default_location_state().permission()); + + let access_type = perm.strongest_allowed_child_access(protected); + WildcardState::update_exposure( + id, + access_type, + &self.nodes, + &mut loc.wildcard_accesses, + ); + } + } + + /// This updates the wildcard tracking data structure to reflect the release of + /// the protector on `tag`. + pub(super) fn update_exposure_for_protector_release(&mut self, tag: BorTag) { + let idx = self.tag_mapping.get(&tag).unwrap(); + + // We check if the node is already exposed, as we don't want to expose any + // nodes which aren't already exposed. + + if self.nodes.get(idx).unwrap().is_exposed { + // Updates the exposure to the new permission on every location. + self.expose_tag(tag, /* protected */ false); + } + } +} + +#[cfg(feature = "expensive-consistency-checks")] +impl Tree { + /// Checks that the wildcard tracking data structure is internally consistent and + /// has the correct `exposed_as` values. + pub fn verify_wildcard_consistency(&self, global: &GlobalState) { + let protected_tags = &global.borrow().protected_tags; + for (_, loc) in self.locations.iter_all() { + let wildcard_accesses = &loc.wildcard_accesses; + let perms = &loc.perms; + // Checks if accesses is empty. + if wildcard_accesses.is_empty() { + return; + } + for (id, node) in self.nodes.iter() { + let state = wildcard_accesses.get(id).unwrap(); + + let expected_exposed_as = if node.is_exposed { + let perm = perms.get(id).unwrap(); + + perm.permission() + .strongest_allowed_child_access(protected_tags.contains_key(&node.tag)) + } else { + WildcardAccessLevel::None + }; + + // The foreign wildcard accesses possible at a node are determined by which + // accesses can originate from their siblings, their parent, and from above + // their parent. + let expected_max_foreign_access = if let Some(parent) = node.parent { + let parent_node = self.nodes.get(parent).unwrap(); + let parent_state = wildcard_accesses.get(parent).unwrap(); + + let max_sibling_access = parent_node + .children + .iter() + .copied() + .filter(|child| *child != id) + .map(|child| { + let state = wildcard_accesses.get(child).unwrap(); + state.max_local_access() + }) + .fold(WildcardAccessLevel::None, max); + + max_sibling_access + .max(parent_state.max_foreign_access) + .max(parent_state.exposed_as) + } else { + WildcardAccessLevel::None + }; + + // Count how many children can be the source of wildcard reads or writes + // (either directly, or via their children). + let child_accesses = node.children.iter().copied().map(|child| { + let state = wildcard_accesses.get(child).unwrap(); + state.max_local_access() + }); + let expected_child_reads = + child_accesses.clone().filter(|a| *a >= WildcardAccessLevel::Read).count(); + let expected_child_writes = + child_accesses.filter(|a| *a >= WildcardAccessLevel::Write).count(); + + assert_eq!( + expected_exposed_as, state.exposed_as, + "tag {:?} (id:{id:?}) should be exposed as {expected_exposed_as:?} but is exposed as {:?}", + node.tag, state.exposed_as + ); + assert_eq!( + expected_max_foreign_access, state.max_foreign_access, + "expected {:?}'s (id:{id:?}) max_foreign_access to be {:?} instead of {:?}", + node.tag, expected_max_foreign_access, state.max_foreign_access + ); + let child_reads: usize = state.child_reads.into(); + assert_eq!( + expected_child_reads, child_reads, + "expected {:?}'s (id:{id:?}) child_reads to be {} instead of {}", + node.tag, expected_child_reads, child_reads + ); + let child_writes: usize = state.child_writes.into(); + assert_eq!( + expected_child_writes, child_writes, + "expected {:?}'s (id:{id:?}) child_writes to be {} instead of {}", + node.tag, expected_child_writes, child_writes + ); + } + } + } +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/dealloc.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/dealloc.rs new file mode 100644 index 0000000000000..c314a96a44312 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/dealloc.rs @@ -0,0 +1,21 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks that deallocation through a wildcard ref fails, +/// if all exposed references are disabled. +pub fn main() { + use std::alloc::Layout; + let x = unsafe { std::alloc::alloc_zeroed(Layout::new::()) as *mut u32 }; + + let ref1 = unsafe { &mut *x }; + let ref2 = unsafe { &mut *x }; + + let int = ref1 as *mut u32 as usize; + let wild = int as *mut u32; + // Disables ref1 and therefore also wild. + *ref2 = 14; + + // Tries to dealloc through a wildcard reference even though all exposed + // references are disabled. + + unsafe { std::alloc::dealloc(wild as *mut u8, Layout::new::()) }; //~ ERROR: /deallocation through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/dealloc.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/dealloc.stderr new file mode 100644 index 0000000000000..a30a45e64b306 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/dealloc.stderr @@ -0,0 +1,14 @@ +error: Undefined Behavior: deallocation through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/dealloc.rs:LL:CC + | +LL | unsafe { std::alloc::dealloc(wild as *mut u8, Layout::new::()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: there are no exposed tags which may perform this access here + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/gc.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/gc.rs new file mode 100644 index 0000000000000..b46f0670bee03 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/gc.rs @@ -0,0 +1,20 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +#[path = "../../../utils/mod.rs"] +mod utils; + +/// Checks that the garbage collector doesn't remove any exposed tags. +fn main() { + let mut _x: u32 = 4; + let int = { + let y = &_x; + y as *const u32 as usize + }; + // If y wasn't exposed, this would gc it. + utils::run_provenance_gc(); + // This should disable y. + _x = 5; + let wild = int as *const u32; + + let _fail = unsafe { *wild }; //~ ERROR: /read access through at .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/gc.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/gc.stderr new file mode 100644 index 0000000000000..4ca2735df592b --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/gc.stderr @@ -0,0 +1,14 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/gc.rs:LL:CC + | +LL | let _fail = unsafe { *wild }; + | ^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: there are no exposed tags which may perform this access here + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child.rs new file mode 100644 index 0000000000000..2187fca16ca19 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child.rs @@ -0,0 +1,64 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks that disabling an exposed reference correctly narrows the +/// possible locations a wildcard access could happen from. +/// Also checks that an access is treated as foreign, if all exposed +/// (non-disabled) references are ancestors. +pub fn main() { + let mut x: u32 = 42; + + let ref1 = &mut x; + let int1 = ref1 as *mut u32 as usize; + + let ref2 = &mut *ref1; + + let ref3 = &mut *ref2; + let _int3 = ref3 as *mut u32 as usize; + + // Write through ref3 so that all references are active. + *ref3 = 43; + + let wild = int1 as *mut u32; + + // ┌────────────┐ + // │ │ + // │ ref1(Act)* │ + // │ │ + // └──────┬─────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref2(Act) │ + // │ │ + // └──────┬─────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref3(Act)* │ + // │ │ + // └────────────┘ + + // Writes through either ref1 or ref3, which is either a child or foreign + // access to ref2. + unsafe { wild.write(42) }; + + // Reading from ref2 still works, since the previous access could have been + // through its child. + // This also freezes ref3. + let _x = *ref2; + + // We can still write through wild, as there is still the exposed ref1 with + // write permissions under proper exposed provenance, this would be UB as the + // only tag wild can assume to not invalidate ref2 is ref3, which we just + // invalidated. + // + // This disables ref2, ref3. + unsafe { wild.write(43) }; + + // Fails because ref2 is disabled. + let _fail = *ref2; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child.stderr new file mode 100644 index 0000000000000..3d450cf784037 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/multi_exposed_child.rs:LL:CC + | +LL | let _fail = *ref2; + | ^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: the accessed tag has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/multi_exposed_child.rs:LL:CC + | +LL | let ref2 = &mut *ref1; + | ^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/multi_exposed_child.rs:LL:CC + | +LL | unsafe { wild.write(43) }; + | ^^^^^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.rs new file mode 100644 index 0000000000000..39c6f315e1413 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.rs @@ -0,0 +1,47 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks if we correctly determine the correct exposed reference a write +/// access could happen through, +/// if there are also exposed reference through which only a read could happen. +pub fn main() { + let mut x: u32 = 42; + + let ref1 = &mut x; + let int1 = ref1 as *mut u32 as usize; + + let ref2 = &mut *ref1; + + let ref3 = &*ref2; + let _int3 = ref3 as *const u32 as usize; + + let wild = int1 as *mut u32; + + // ┌────────────┐ + // │ │ + // │ ref1(Res)* │ + // │ │ + // └──────┬─────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref2(Res) │ + // │ │ + // └──────┬─────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref3(Frz)* │ + // │ │ + // └────────────┘ + + // Writes through ref1 as we cannot write through ref3 since it's frozen. + // Disables ref2, ref3. + unsafe { wild.write(42) }; + + // ref2 is disabled. + let _fail = *ref2; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.stderr new file mode 100644 index 0000000000000..402529cbc3878 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.rs:LL:CC + | +LL | let _fail = *ref2; + | ^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: the accessed tag has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.rs:LL:CC + | +LL | let ref2 = &mut *ref1; + | ^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/multi_exposed_child_unique_writer.rs:LL:CC + | +LL | unsafe { wild.write(42) }; + | ^^^^^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_disable.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_disable.rs new file mode 100644 index 0000000000000..2622e9a62ab7d --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_disable.rs @@ -0,0 +1,38 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks with multiple exposed nodes, that if they are all disabled +/// then no wildcard accesses are possible. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + let ref3 = unsafe { &mut *ptr_base }; + + // Both references get exposed. + let int1 = ref1 as *mut u32 as usize; + let _int2 = ref2 as *mut u32 as usize; + + let wild = int1 as *mut u32; + + // ┌────────────┐ + // │ │ + // │ ptr_base ├──────────────┬───────────────────┐ + // │ │ │ │ + // └──────┬─────┘ │ │ + // │ │ │ + // │ │ │ + // ▼ ▼ ▼ + // ┌────────────┐ ┌────────────┐ ┌───────────┐ + // │ │ │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res)* │ │ ref3(Res) │ + // │ │ │ │ │ │ + // └────────────┘ └────────────┘ └───────────┘ + + // Disables ref1,ref2. + *ref3 = 13; + + // Both exposed references are disabled so this fails. + let _fail = unsafe { *wild }; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_disable.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_disable.stderr new file mode 100644 index 0000000000000..bc659d7febf3a --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_disable.stderr @@ -0,0 +1,14 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_disable.rs:LL:CC + | +LL | let _fail = unsafe { *wild }; + | ^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: there are no exposed tags which may perform this access here + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.rs new file mode 100644 index 0000000000000..c889f57552d66 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.rs @@ -0,0 +1,38 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks that if for a node all exposed references are foreign, +/// that a wildcard access gets treated as foreign to it. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + let ref3 = unsafe { &mut *ptr_base }; + + // Both references get exposed. + let int1 = ref1 as *mut u32 as usize; + let _int2 = ref2 as *mut u32 as usize; + + let wild = int1 as *mut u32; + + // ┌────────────┐ + // │ │ + // │ ptr_base ├──────────────┬───────────────────┐ + // │ │ │ │ + // └──────┬─────┘ │ │ + // │ │ │ + // │ │ │ + // ▼ ▼ ▼ + // ┌────────────┐ ┌────────────┐ ┌───────────┐ + // │ │ │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res)* │ │ ref3(Res) │ + // │ │ │ │ │ │ + // └────────────┘ └────────────┘ └───────────┘ + + // Disables ref3 as both exposed pointers are foreign to it. + unsafe { wild.write(13) }; + + // Fails because ref3 is disabled. + let _fail = *ref3; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.stderr new file mode 100644 index 0000000000000..85c836b4b36f1 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.rs:LL:CC + | +LL | let _fail = *ref3; + | ^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: the accessed tag has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.rs:LL:CC + | +LL | let ref3 = unsafe { &mut *ptr_base }; + | ^^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_foreign.rs:LL:CC + | +LL | unsafe { wild.write(13) }; + | ^^^^^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.rs new file mode 100644 index 0000000000000..b47eaf839ced1 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.rs @@ -0,0 +1,50 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks if a local access gets correctly triggered, if we know that +/// all exposed references are local to a node. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + + // Both references get exposed. + let int1 = ref1 as *mut u32 as usize; + let _int2 = ref2 as *mut u32 as usize; + + let wild = int1 as *mut u32; + + // Activates ptr_base. + unsafe { wild.write(41) }; + + // ┌─────────────┐ + // │ │ + // │ x (Act) │ + // │ │ + // └──────┬──────┘ + // │ + // │ + // ▼ + // ┌────────────────┐ + // │ │ + // │ ptr_base (Act) ├──────────┐ + // │ │ │ + // └──────┬─────────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res)* │ + // │ │ │ │ + // └────────────┘ └────────────┘ + + // We read from x causing a foreign access to ptr_base, freezing it + // (as the previous wildcard access has made it active). + let _y = x; + + // While both exposed references are still enabled for writes, any write + // through them would cause UB at ptr_base. + unsafe { wild.write(0) }; //~ ERROR: /write access through at .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.stderr new file mode 100644 index 0000000000000..ca4a2533f7b68 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.stderr @@ -0,0 +1,32 @@ +error: Undefined Behavior: write access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.rs:LL:CC + | +LL | unsafe { wild.write(0) }; + | ^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: the accessed tag is a child of the conflicting tag + = help: the conflicting tag has state Frozen which forbids this child write access +help: the conflicting tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.rs:LL:CC + | +LL | let ptr_base = &mut x as *mut u32; + | ^^^^^^ +help: the conflicting tag later transitioned to Unique due to a child write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.rs:LL:CC + | +LL | unsafe { wild.write(41) }; + | ^^^^^^^^^^^^^^ + = help: this transition corresponds to the first write to a 2-phase borrowed mutable reference +help: the conflicting tag later transitioned to Frozen due to a foreign read access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_local.rs:LL:CC + | +LL | let _y = x; + | ^ + = help: this transition corresponds to a loss of write permissions + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.rs new file mode 100644 index 0000000000000..fb0b43f20dc15 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.rs @@ -0,0 +1,38 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks if we correctly determine the correct exposed reference a write +/// access could happen through, if there are also exposed reference +/// through which only a read access could happen. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &*ptr_base }; + + // Both references get exposed. + let int1 = ref1 as *mut u32 as usize; + let _int2 = ref2 as *const u32 as usize; + + let wild = int1 as *mut u32; + + // ┌────────────┐ + // │ │ + // │ ptr_base ├──────────────┐ + // │ │ │ + // └──────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ ref1(Res)* │ │ ref2(Frz)* │ + // │ │ │ │ + // └────────────┘ └────────────┘ + + // Disables ref2 as the only write could happen through ref1. + unsafe { wild.write(13) }; + + // Fails because ref2 is disabled. + let _fail = *ref2; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.stderr new file mode 100644 index 0000000000000..a07febaa84c94 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.rs:LL:CC + | +LL | let _fail = *ref2; + | ^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: the accessed tag has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Frozen + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.rs:LL:CC + | +LL | let ref2 = unsafe { &*ptr_base }; + | ^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/multi_exposed_siblings_unique_writer.rs:LL:CC + | +LL | unsafe { wild.write(13) }; + | ^^^^^^^^^^^^^^ + = help: this transition corresponds to a loss of read permissions + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.rs new file mode 100644 index 0000000000000..620cf34d2a088 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.rs @@ -0,0 +1,26 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks that wildcard accesses correctly infers the allowed permissions +/// on protected conflicted pointers. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + + let protect = |arg: &mut u32| { + // Expose arg. + let int = arg as *mut u32 as usize; + let wild = int as *mut u32; + + // Does a foreign read to arg marking it as conflicted and making child + // writes UB while it's protected. + let _x = *ref2; + + // The only exposed reference (arg) doesn't allow child writes, so this is UB. + unsafe { *wild = 4 }; //~ ERROR: /write access through at .* is forbidden/ + }; + + protect(ref1); +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr new file mode 100644 index 0000000000000..5486eee4f063f --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/protector_conflicted.stderr @@ -0,0 +1,21 @@ +error: Undefined Behavior: write access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/protector_conflicted.rs:LL:CC + | +LL | unsafe { *wild = 4 }; + | ^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: there are no exposed tags which may perform this access here + = note: BACKTRACE: + = note: inside closure at tests/fail/tree_borrows/wildcard/protector_conflicted.rs:LL:CC +note: inside `main` + --> tests/fail/tree_borrows/wildcard/protector_conflicted.rs:LL:CC + | +LL | protect(ref1); + | ^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_disable.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_disable.rs new file mode 100644 index 0000000000000..1f2236a70f59f --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_disable.rs @@ -0,0 +1,35 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks that with only one exposed reference, that if this reference gets +/// disabled no wildcard accesses are possible. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + + let int1 = ref1 as *mut u32 as usize; + let wild = int1 as *mut u32; + + // ┌────────────┐ + // │ │ + // │ ptr_base ├───────────┐ + // │ │ │ + // └──────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌───────────┐ + // │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res) │ + // │ │ │ │ + // └────────────┘ └───────────┘ + + // Disables ref1. + *ref2 = 13; + + // Tries to do a wildcard access through the only exposed reference ref1, + // which is disabled. + let _fail = unsafe { *wild }; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_disable.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_disable.stderr new file mode 100644 index 0000000000000..170d00694d10a --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_disable.stderr @@ -0,0 +1,14 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/single_exposed_disable.rs:LL:CC + | +LL | let _fail = unsafe { *wild }; + | ^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: there are no exposed tags which may perform this access here + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_foreign.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_foreign.rs new file mode 100644 index 0000000000000..d8f2ab16eeb76 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_foreign.rs @@ -0,0 +1,34 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks that with only one exposed reference, wildcard accesses +/// correctly cause foreign accesses. +pub fn main() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + + let int1 = ref1 as *mut u32 as usize; + let wild = int1 as *mut u32; + + // ┌────────────┐ + // │ │ + // │ ptr_base ├───────────┐ + // │ │ │ + // └──────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌───────────┐ + // │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res) │ + // │ │ │ │ + // └────────────┘ └───────────┘ + + // Write through the wildcard to the only exposed reference ref1, + // disabling ref2. + unsafe { wild.write(13) }; + + let _fail = *ref2; //~ ERROR: /read access through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_foreign.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_foreign.stderr new file mode 100644 index 0000000000000..98d22598d6580 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_foreign.stderr @@ -0,0 +1,25 @@ +error: Undefined Behavior: read access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/single_exposed_foreign.rs:LL:CC + | +LL | let _fail = *ref2; + | ^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: the accessed tag has state Disabled which forbids this child read access +help: the accessed tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/single_exposed_foreign.rs:LL:CC + | +LL | let ref2 = unsafe { &mut *ptr_base }; + | ^^^^^^^^^^^^^^ +help: the accessed tag later transitioned to Disabled due to a foreign write access at offsets [0x0..0x4] + --> tests/fail/tree_borrows/wildcard/single_exposed_foreign.rs:LL:CC + | +LL | unsafe { wild.write(13) }; + | ^^^^^^^^^^^^^^ + = help: this transition corresponds to a loss of read and write permissions + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_local.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_local.rs new file mode 100644 index 0000000000000..e5a246c505473 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_local.rs @@ -0,0 +1,22 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// Checks if a local access gets correctly triggered during wildcard access, +/// if we know that the only exposed reference is local to the node. +pub fn main() { + let mut x: u32 = 0; + + let ref1 = &mut x; + + let int = ref1 as *mut u32 as usize; + let wild = int as *mut u32; + + // Activates ref1. + unsafe { wild.write(41) }; + + // Reads from x causing a foreign read on ref1, freezing it + // (because it was active). + let _y = x; + + // The only exposed reference (ref1) is frozen, so wildcard writes are UB. + unsafe { wild.write(0) }; //~ ERROR: /write access through at .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_local.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_local.stderr new file mode 100644 index 0000000000000..a33cd5519da4d --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_local.stderr @@ -0,0 +1,14 @@ +error: Undefined Behavior: write access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/single_exposed_local.rs:LL:CC + | +LL | unsafe { wild.write(0) }; + | ^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: there are no exposed tags which may perform this access here + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_only_ro.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_only_ro.rs new file mode 100644 index 0000000000000..c8e75636a07dd --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_only_ro.rs @@ -0,0 +1,11 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +/// If we have only exposed read-only pointers, doing a write through a +/// wildcard ptr should fail. +fn main() { + let mut x = 0; + let _fool = &mut x as *mut i32; // this would have fooled the old untagged pointer logic + let addr = (&x as *const i32).expose_provenance(); + let ptr = std::ptr::with_exposed_provenance_mut::(addr); + unsafe { *ptr = 0 }; //~ ERROR: /write access through at .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_only_ro.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_only_ro.stderr new file mode 100644 index 0000000000000..2d643a852e4cd --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/single_exposed_only_ro.stderr @@ -0,0 +1,14 @@ +error: Undefined Behavior: write access through at ALLOC[0x0] is forbidden + --> tests/fail/tree_borrows/wildcard/single_exposed_only_ro.rs:LL:CC + | +LL | unsafe { *ptr = 0 }; + | ^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: there are no exposed tags which may perform this access here + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs b/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs new file mode 100644 index 0000000000000..71e98e7056021 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs @@ -0,0 +1,15 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance +//@error-in-other-file: /deallocation through .* is forbidden/ + +fn inner(x: &mut i32, f: fn(usize)) { + // `f` may mutate, but it may not deallocate! + // `f` takes a raw pointer so that the only protector + // is that on `x` + f(x as *mut i32 as usize) +} + +fn main() { + inner(Box::leak(Box::new(0)), |raw| { + drop(unsafe { Box::from_raw(raw as *mut i32) }); + }); +} diff --git a/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr b/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr new file mode 100644 index 0000000000000..de92cf91e3e85 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.stderr @@ -0,0 +1,42 @@ +error: Undefined Behavior: deallocation through at ALLOC[0x0] is forbidden + --> RUSTLIB/alloc/src/boxed.rs:LL:CC + | +LL | self.1.deallocate(From::from(ptr.cast()), layout); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information + = help: the allocation of the accessed tag also contains the strongly protected tag + = help: the strongly protected tag disallows deallocations +help: the strongly protected tag was created here, in the initial state Reserved + --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC + | +LL | fn inner(x: &mut i32, f: fn(usize)) { + | ^ + = note: BACKTRACE (of the first span): + = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC + = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC +note: inside closure + --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC + | +LL | drop(unsafe { Box::from_raw(raw as *mut i32) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: inside `<{closure@tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC} as std::ops::FnOnce<(usize,)>>::call_once - shim` at RUSTLIB/core/src/ops/function.rs:LL:CC +note: inside `inner` + --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC + | +LL | f(x as *mut i32 as usize) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: inside `main` + --> tests/fail/tree_borrows/wildcard/strongly_protected_wildcard.rs:LL:CC + | +LL | / inner(Box::leak(Box::new(0)), |raw| { +LL | | drop(unsafe { Box::from_raw(raw as *mut i32) }); +LL | | }); + | |______^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/pass/stacked_borrows/int-to-ptr.rs b/src/tools/miri/tests/pass/both_borrows/int-to-ptr.rs similarity index 97% rename from src/tools/miri/tests/pass/stacked_borrows/int-to-ptr.rs rename to src/tools/miri/tests/pass/both_borrows/int-to-ptr.rs index 8a05fca3f312f..830feed7e2b01 100644 --- a/src/tools/miri/tests/pass/stacked_borrows/int-to-ptr.rs +++ b/src/tools/miri/tests/pass/both_borrows/int-to-ptr.rs @@ -1,4 +1,6 @@ +//@revisions: stack tree //@compile-flags: -Zmiri-permissive-provenance +//@[tree]compile-flags: -Zmiri-tree-borrows use std::ptr; // Just to make sure that casting a ref to raw, to int and back to raw diff --git a/src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.rs b/src/tools/miri/tests/pass/both_borrows/issue-miri-2389.rs similarity index 86% rename from src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.rs rename to src/tools/miri/tests/pass/both_borrows/issue-miri-2389.rs index 469122095e512..f9d87b7dea8fe 100644 --- a/src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.rs +++ b/src/tools/miri/tests/pass/both_borrows/issue-miri-2389.rs @@ -1,3 +1,6 @@ +//@revisions: stack tree +//@compile-flags: -Zmiri-permissive-provenance +//@[tree]compile-flags: -Zmiri-tree-borrows use std::cell::Cell; fn main() { diff --git a/src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.stderr b/src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.stderr deleted file mode 100644 index 363f8a20f8daa..0000000000000 --- a/src/tools/miri/tests/pass/stacked_borrows/issue-miri-2389.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: integer-to-pointer cast - --> tests/pass/stacked_borrows/issue-miri-2389.rs:LL:CC - | -LL | let wildcard = &root0 as *const Cell as usize as *const Cell; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead - = help: you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics - = help: alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning - diff --git a/src/tools/miri/tests/pass/tree_borrows/wildcard/undetected_ub.rs b/src/tools/miri/tests/pass/tree_borrows/wildcard/undetected_ub.rs new file mode 100644 index 0000000000000..c34fbcb50119b --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/wildcard/undetected_ub.rs @@ -0,0 +1,145 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance +// NOTE: This file documents UB that is not detected by wildcard provenance. + +pub fn main() { + uncertain_provenance(); + protected_exposed(); + protected_wildcard(); +} + +/// Currently, if we do not know for a tag if an access is local or foreign, +/// then we do not do any state transitions on that tag. However, to implement +/// proper provenance we would have to instead pick the correct transition +/// non-deterministically. +/// +/// This test contains such UB that will not be detectable with wildcard provenance, +/// but would be detectable if we implemented this behavior correctly. +pub fn uncertain_provenance() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + // We create 2 mutable references, each with a unique tag. + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + + // Both references get exposed. + let int1 = ref1 as *mut u32 as usize; + let _int2 = ref2 as *mut u32 as usize; + //ref1 : Reserved + //ref2 : Reserved + + // We need to pick the "correct" tag for wild from the exposed tags. + let wild = int1 as *mut u32; + // wild=ref1 wild=ref2 + //ref1 : Reserved Reserved + //ref2 : Reserved Reserved + + // We write to wild, disabling the other tag. + unsafe { wild.write(13) }; + // wild=ref1 wild=ref2 + //ref1 : Unique Disabled + //ref2 : Disabled Unique + + // We access both references, even though one of them should be + // disabled under proper exposed provenance. + // This is UB, however, wildcard provenance cannot detect this. + assert_eq!(*ref1, 13); + // wild=ref1 wild=ref2 + //ref1 : Unique UB + //ref2 : Disabled Frozen + assert_eq!(*ref2, 13); + // wild=ref1 wild=ref2 + //ref1 : Frozen UB + //ref2 : UB Frozen +} + +/// If a reference is protected, then all foreign writes to it cause UB. +/// This effectively means any write needs to happen through a child of +/// the protected reference. +/// With this information we could further narrow the possible candidates +/// for a wildcard write. +/// However, currently tree borrows doesn't do this, so this test has UB +/// that isn't detected. +pub fn protected_exposed() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + + let _int2 = ref2 as *mut u32 as usize; + + fn protect(ref3: &mut u32) { + let int3 = ref3 as *mut u32 as usize; + + // ┌────────────┐ + // │ │ + // │ ptr_base ├──────────────┐ + // │ │ │ + // └──────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ ref1(Res) │ │ ref2(Res)* │ + // │ │ │ │ + // └──────┬─────┘ └────────────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref3(Res)* │ + // │ │ + // └────────────┘ + + // Since ref3 is protected, we could know that every write from outside it will be UB. + // This means we know that the access is through ref3, disabling ref2. + let wild = int3 as *mut u32; + unsafe { wild.write(13) } + } + protect(ref1); + + // ref2 is disabled, so this read causes UB, but we currently don't protect this. + let _fail = *ref2; +} + +/// Currently, we do not assign protectors to wildcard references. +/// This test has UB because it does a foreign write to a protected reference. +/// However, that reference is a wildcard, so this doesn't get detected. +#[allow(unused_variables)] +pub fn protected_wildcard() { + let mut x: u32 = 32; + let ref1 = &mut x; + let ref2 = &mut *ref1; + + let int = ref2 as *mut u32 as usize; + let wild = int as *mut u32; + let wild_ref = unsafe { &mut *wild }; + + let mut protect = |arg: &mut u32| { + // arg is a protected pointer with wildcard provenance. + + // ┌────────────┐ + // │ │ + // │ ref1(Res) │ + // │ │ + // └──────┬─────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref2(Res)* │ + // │ │ + // └────────────┘ + + // Writes to ref1, disabling ref2, i.e. disabling all exposed references. + // Since a wildcard reference is protected, this is UB. But we currently don't detect this. + *ref1 = 13; + }; + + // We pass a pointer with wildcard provenance to the function. + protect(wild_ref); +} diff --git a/src/tools/miri/tests/pass/tree_borrows/wildcard/wildcard.rs b/src/tools/miri/tests/pass/tree_borrows/wildcard/wildcard.rs new file mode 100644 index 0000000000000..c406bfe01f62c --- /dev/null +++ b/src/tools/miri/tests/pass/tree_borrows/wildcard/wildcard.rs @@ -0,0 +1,171 @@ +//@compile-flags: -Zmiri-tree-borrows -Zmiri-permissive-provenance + +pub fn main() { + multiple_exposed_siblings(); + multiple_exposed_child(); + dealloc(); + protector(); + protector_conflicted_release(); + returned_mut_is_usable(); +} + +/// Checks that an access through a wildcard reference +/// doesn't disable any exposed references. +/// It tests this with exposed references that are siblings of each other. +pub fn multiple_exposed_siblings() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + + // Both references get exposed. + let int1 = ref1 as *mut u32 as usize; + let _int2 = ref2 as *mut u32 as usize; + + let wild = int1 as *mut u32; + + // ┌────────────┐ + // │ │ + // │ ptr_base ├────────────┐ + // │ │ │ + // └──────┬─────┘ │ + // │ │ + // │ │ + // ▼ ▼ + // ┌────────────┐ ┌────────────┐ + // │ │ │ │ + // │ ref1(Res)* │ │ ref2(Res)* │ + // │ │ │ │ + // └────────────┘ └────────────┘ + + // Writes through either of the two exposed references. + // We do not know which so we cannot disable the other. + unsafe { wild.write(13) }; + + // Reading through either of these references should be valid. + assert_eq!(*ref2, 13); +} + +/// Checks that an access through a wildcard reference +/// doesn't disable any exposed references. +/// It tests this with exposed references where one is the ancestor of the other. +pub fn multiple_exposed_child() { + let mut x: u32 = 42; + + let ref1 = &mut x; + let int1 = ref1 as *mut u32 as usize; + + let ref2 = &mut *ref1; + + let ref3 = &mut *ref2; + let _int3 = ref3 as *mut u32 as usize; + + let wild = int1 as *mut u32; + + // ┌────────────┐ + // │ │ + // │ ref1(Res)* │ + // │ │ + // └──────┬─────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref2(Res) │ + // │ │ + // └──────┬─────┘ + // │ + // │ + // ▼ + // ┌────────────┐ + // │ │ + // │ ref3(Res)* │ + // │ │ + // └────────────┘ + + // This writes either through ref1 or ref3, which is either a child or foreign access to ref2. + unsafe { wild.write(42) }; + + // Reading from ref2 still works, since the previous access could have been through its child. + // This also freezes ref3. + let _x = *ref2; + + // We can still write through wild, as there is still the exposed ref1 with write permissions. + unsafe { wild.write(43) }; +} + +/// Checks that we can deallocate through a wildcard reference. +fn dealloc() { + use std::alloc::Layout; + let x = unsafe { std::alloc::alloc_zeroed(Layout::new::()) as *mut u32 }; + let ref1 = unsafe { &mut *x }; + let int = ref1 as *mut u32 as usize; + let wild = int as *mut u32; + + unsafe { std::alloc::dealloc(wild as *mut u8, Layout::new::()) }; +} + +/// Checks that we can pass a wildcard reference to a function. +fn protector() { + fn protect(arg: &mut u32) { + *arg = 4; + } + let mut x: u32 = 32; + let ref1 = &mut x; + let int = ref1 as *mut u32 as usize; + let wild = int as *mut u32; + let wild_ref = unsafe { &mut *wild }; + + protect(wild_ref); + + assert_eq!(*ref1, 4); +} + +/// Checks whether we correctly handle the protector being released on +/// a conflicted exposed reference. +fn protector_conflicted_release() { + let mut x: u32 = 42; + + let ptr_base = &mut x as *mut u32; + let ref1 = unsafe { &mut *ptr_base }; + let ref2 = unsafe { &mut *ptr_base }; + + let protect = |arg: &mut u32| { + // Expose arg. + let int = arg as *mut u32 as usize; + let wild = int as *mut u32; + + // Do a foreign read to arg marking it as conflicted and making child_writes UB while its protected. + let _x = *ref2; + + return wild; + }; + + let wild = protect(ref1); + + // The protector on arg got released so writes through arg should work again. + unsafe { *wild = 4 }; +} + +/// Analogous to same test in `../tree-borrows.rs` but with a protected wildcard reference. +fn returned_mut_is_usable() { + // NOTE: Currently we ignore protectors on wildcard references. + fn reborrow(x: &mut u8) -> &mut u8 { + let y = &mut *x; + // Activate the reference so that it is vulnerable to foreign reads. + *y = *y; + y + // An implicit read through `x` is inserted here. + } + let mut x: u8 = 0; + let ref1 = &mut x; + let int = ref1 as *mut u8 as usize; + let wild = int as *mut u8; + let wild_ref = unsafe { &mut *wild }; + + let y = reborrow(wild_ref); + + *y = 1; +} From daf7b0184c753722902fa58ee0e304e211044193 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 17 Nov 2025 11:34:28 +0100 Subject: [PATCH 12/13] emit stash diagnostics before flushing delayed errors --- src/tools/miri/src/bin/miri.rs | 19 +++++++++++++------ .../issue-miri-4698-stashed-diagnostic.rs | 10 ++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 src/tools/miri/tests/pass/issues/issue-miri-4698-stashed-diagnostic.rs diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index 9ce2aab8658f2..7e80e52041f87 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -158,19 +158,24 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { _: &rustc_interface::interface::Compiler, tcx: TyCtxt<'tcx>, ) -> Compilation { + // Compilation is done, interpretation is starting. Deal with diagnostics from the + // compilation part. We cannot call `sess.finish_diagnostics()` as then "aborting due to + // previous errors" gets printed twice. + tcx.dcx().emit_stashed_diagnostics(); tcx.dcx().abort_if_errors(); tcx.dcx().flush_delayed(); + // Miri is taking over. Start logging. + init_late_loggers(&EarlyDiagCtxt::new(tcx.sess.opts.error_format), tcx); + + // Find the entry point. if !tcx.crate_types().contains(&CrateType::Executable) { tcx.dcx().fatal("miri only makes sense on bin crates"); } - - let early_dcx = EarlyDiagCtxt::new(tcx.sess.opts.error_format); - init_late_loggers(&early_dcx, tcx); - let (entry_def_id, entry_type) = entry_fn(tcx); - let mut config = self.miri_config.take().expect("after_analysis must only be called once"); + // Obtain and complete the Miri configuration. + let mut config = self.miri_config.take().expect("after_analysis must only be called once"); // Add filename to `miri` arguments. config.args.insert(0, tcx.sess.io.input.filestem().to_string()); @@ -179,6 +184,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { env::set_current_dir(cwd).unwrap(); } + // Emit warnings for some unusual configurations. if tcx.sess.opts.optimize != OptLevel::No { tcx.dcx().warn("Miri does not support optimizations: the opt-level is ignored. The only effect \ of selecting a Cargo profile that enables optimizations (such as --release) is to apply \ @@ -193,6 +199,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { optimizations is usually marginal at best."); } + // Invoke the interpreter. let res = if config.genmc_config.is_some() { assert!(self.many_seeds.is_none()); run_genmc_mode(tcx, &config, |genmc_ctx: Rc| { @@ -209,7 +216,7 @@ impl rustc_driver::Callbacks for MiriCompilerCalls { } else { miri::eval_entry(tcx, entry_def_id, entry_type, &config, None) }; - + // Process interpreter result. if let Err(return_code) = res { tcx.dcx().abort_if_errors(); exit(return_code.get()); diff --git a/src/tools/miri/tests/pass/issues/issue-miri-4698-stashed-diagnostic.rs b/src/tools/miri/tests/pass/issues/issue-miri-4698-stashed-diagnostic.rs new file mode 100644 index 0000000000000..3467d2d273797 --- /dev/null +++ b/src/tools/miri/tests/pass/issues/issue-miri-4698-stashed-diagnostic.rs @@ -0,0 +1,10 @@ +// This test seems to involve a "stashed diagnostic" (or at least it used to at the time of +// writing). Ensure we handle that correctly. + +pub trait Trait { + type Assoc: Assoc; +} + +pub trait Assoc {} + +fn main() {} From eafd125d1f8c228e136b8e371955ade8fd023fcc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 17 Nov 2025 13:34:27 +0100 Subject: [PATCH 13/13] update lockfile --- Cargo.lock | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9350112939bd6..9dce64ce66ab6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -396,7 +396,7 @@ dependencies = [ name = "cargo-miri" version = "0.1.0" dependencies = [ - "cargo_metadata 0.21.0", + "cargo_metadata 0.23.1", "directories", "rustc-build-sysroot", "rustc_tools_util 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -423,6 +423,15 @@ dependencies = [ "serde", ] +[[package]] +name = "cargo-platform" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122ec45a44b270afd1402f351b782c676b173e3c3fb28d86ff7ebfb4d86a4ee4" +dependencies = [ + "serde", +] + [[package]] name = "cargo-util-schemas" version = "0.8.2" @@ -468,6 +477,20 @@ dependencies = [ "thiserror 2.0.15", ] +[[package]] +name = "cargo_metadata" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" +dependencies = [ + "camino", + "cargo-platform 0.3.1", + "semver", + "serde", + "serde_json", + "thiserror 2.0.15", +] + [[package]] name = "cargotest2" version = "0.1.0" @@ -2157,6 +2180,16 @@ dependencies = [ "windows-targets 0.53.3", ] +[[package]] +name = "libloading" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" +dependencies = [ + "cfg-if", + "windows-link 0.2.1", +] + [[package]] name = "libm" version = "0.2.15" @@ -2404,7 +2437,7 @@ dependencies = [ "ipc-channel", "libc", "libffi", - "libloading", + "libloading 0.9.0", "measureme", "nix", "rand 0.9.2", @@ -4152,7 +4185,7 @@ version = "0.0.0" dependencies = [ "bitflags", "libc", - "libloading", + "libloading 0.8.8", "odht", "rustc_abi", "rustc_ast",